当前位置: 首页 > 知识库问答 >
问题:

这行代码是什么意思?如何创建此类的对象?

彭星津
2023-03-14

我试图构造MTree类的一个对象(https://github.com/waikato/moa/blob/master/moa/src/main/java/moa/clusterers/outliers/utils/MTree/MTree.java)

MTree的构造函数如下所示:

public MTree(DistanceFunction<? super DATA> distanceFunction,
        SplitFunction<DATA> splitFunction) {
    this(DEFAULT_MIN_NODE_CAPACITY, distanceFunction, splitFunction);
}
/**
 * An object that can calculate the distance between two data objects.
 *
 * @param <DATA> The type of the data objects.
 */
public interface DistanceFunction<DATA> {
    
    double calculate(DATA data1, DATA data2);
    
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Some pre-defined implementations of {@linkplain DistanceFunction distance
 * functions}.
 */
public final class DistanceFunctions {
    
    /**
     * Don't let anyone instantiate this class.
     */
    private DistanceFunctions() {}
    
    
    /**
     * Creates a cached version of a {@linkplain DistanceFunction distance
     * function}. This method is used internally by {@link MTree} to create
     * a cached distance function to pass to the {@linkplain SplitFunction split
     * function}.
     * @param distanceFunction The distance function to create a cached version
     *        of.
     * @return The cached distance function.
     */
    public static <Data> DistanceFunction<Data> cached(final DistanceFunction<Data> distanceFunction) {
        return new DistanceFunction<Data>() {
            class Pair {
                Data data1;
                Data data2;
                
                public Pair(Data data1, Data data2) {
                    this.data1 = data1;
                    this.data2 = data2;
                }

                @Override
                public int hashCode() {
                    return data1.hashCode() ^ data2.hashCode();
                }
                
                @Override
                public boolean equals(Object arg0) {
                    if(arg0 instanceof Pair) {
                        Pair that = (Pair) arg0;
                        return this.data1.equals(that.data1)
                            && this.data2.equals(that.data2);
                    } else {
                        return false;
                    }
                }
            }
            
            private final Map<Pair, Double> cache = new HashMap<Pair, Double>();
            
            @Override
            public double calculate(Data data1, Data data2) {
                Pair pair1 = new Pair(data1, data2);
                Double distance = cache.get(pair1);
                if(distance != null) {
                    return distance;
                }
                
                Pair pair2 = new Pair(data2, data1);
                distance = cache.get(pair2);
                if(distance != null) {
                    return distance;
                }
                
                distance = distanceFunction.calculate(data1, data2);
                cache.put(pair1, distance);
                cache.put(pair2, distance);
                return distance;
            }
        };
    }
    
    
    
    /**
     * An interface to represent coordinates in Euclidean spaces.
     * @see <a href="http://en.wikipedia.org/wiki/Euclidean_space">"Euclidean
     *      Space" article at Wikipedia</a>
     */
    public interface EuclideanCoordinate {
        /**
         * The number of dimensions.
         */
        int dimensions();
        
        /**
         * A method to access the {@code index}-th component of the coordinate.
         * 
         * @param index The index of the component. Must be less than {@link
         *              #dimensions()}. 
         */
        double get(int index);
    }
    
    
    /**
     * Calculates the distance between two {@linkplain EuclideanCoordinate 
     * euclidean coordinates}.
     */
    public static double euclidean(EuclideanCoordinate coord1, EuclideanCoordinate coord2) {
        int size = Math.min(coord1.dimensions(), coord2.dimensions());
        double distance = 0;
        for(int i = 0; i < size; i++) {
            double diff = coord1.get(i) - coord2.get(i);
            distance += diff * diff;
        }
        distance = Math.sqrt(distance);
        return distance;
    }


    /**
     * A {@linkplain DistanceFunction distance function} object that calculates
     * the distance between two {@linkplain EuclideanCoordinate euclidean
     * coordinates}.
     */
    public static final DistanceFunction<EuclideanCoordinate> EUCLIDEAN = new DistanceFunction<DistanceFunctions.EuclideanCoordinate>() {
        @Override
        public double calculate(EuclideanCoordinate coord1, EuclideanCoordinate coord2) {
            return DistanceFunctions.euclidean(coord1, coord2);
        }
    };
    
    
    /**
     * A {@linkplain DistanceFunction distance function} object that calculates
     * the distance between two coordinates represented by {@linkplain 
     * java.util.List lists} of {@link java.lang.Integer}s.
     */
    public static final DistanceFunction<List<Integer>> EUCLIDEAN_INTEGER_LIST = new DistanceFunction<List<Integer>>() {
        @Override
        public double calculate(List<Integer> data1, List<Integer> data2) {
            class IntegerListEuclideanCoordinate implements EuclideanCoordinate {
                List<Integer> list;
                public IntegerListEuclideanCoordinate(List<Integer> list) { this.list = list; }
                @Override public int dimensions() { return list.size(); }
                @Override public double get(int index) { return list.get(index); }
            };
            IntegerListEuclideanCoordinate coord1 = new IntegerListEuclideanCoordinate(data1);
            IntegerListEuclideanCoordinate coord2 = new IntegerListEuclideanCoordinate(data2);
            return DistanceFunctions.euclidean(coord1, coord2);
        }
    };
    
    /**
     * A {@linkplain DistanceFunction distance function} object that calculates
     * the distance between two coordinates represented by {@linkplain 
     * java.util.List lists} of {@link java.lang.Double}s.
     */
    public static final DistanceFunction<List<Double>> EUCLIDEAN_DOUBLE_LIST = new DistanceFunction<List<Double>>() {
        @Override
        public double calculate(List<Double> data1, List<Double> data2) {
            class DoubleListEuclideanCoordinate implements EuclideanCoordinate {
                List<Double> list;
                public DoubleListEuclideanCoordinate(List<Double> list) { this.list = list; }
                @Override public int dimensions() { return list.size(); }
                @Override public double get(int index) { return list.get(index); }
            };
            DoubleListEuclideanCoordinate coord1 = new DoubleListEuclideanCoordinate(data1);
            DoubleListEuclideanCoordinate coord2 = new DoubleListEuclideanCoordinate(data2);
            return DistanceFunctions.euclidean(coord1, coord2);
        }
    };
}

另外,要创建一个MTree对象,我应该创建一个DistanceFunctions对象和一个ComposedSplitFunction对象(它是SplitFunction接口的实现),并将它们作为MTree构造函数的参数输入。但是我真的不知道怎么做,因为在DistanceFunctions类中,构造函数是私有的。所以我不能为mtree的构造函数生成参数。我该怎么办?

新更新:我想要做的是为MTree创建一个Junit测试,我相信我需要做的第一件事是创建一个MTree的对象。

共有1个答案

咸承教
2023-03-14

接口可以有多个实现。它们只是形成了需要遵循的一般合同实现。

这里的cache实现,即接受DistanceFunction作为输入,并保证a和B(或B和a)之间的距离值只计算一次,然后从内部cache映射提供。cache函数的泛型类型只是保证可以向它传递任何类型。即。您可以有一个最简单的实现,它只接受两个整数,并计算它们之间的差值,如下所示:

DistanceFunction<Integer> func = (Integer a, Integer b) -> Math.abs(a - b);

这是一个labmda表达式,也可以像这样写得更详细一点

DistanceFunction<Integer> func = new DistanceFunction<Integer>() {
    @Override
    public double calculate(Integer data1, Integer data2) {
        return Math.abs(data1 - data2);
    }
};
DistanceFunction<Integer> cache = DistanceFunctions.cached(func);
double distance = cache.calculate(10, 5);
java prettyprint-override">distance = cache.calculate(10, 5);
distance = cache.calculate(5, 10);
MTree mTree = new MTree(EUCLIDEAN_INTEGER_LIST, new SplitFunction<List<Integer>>(...) {

    ...

    @Override
    public SplitResult<List<Integer>> process(Set<List<Integer>> dataSet, DistanceFunction<? super List<Integer>> distanceFunction) {
        Pair<List<Integer>> promoted = ...
        Pair<Set<List<Integer>>> partitions = ...
        return new SplitResult<List<Integer>>(promoted, partitions);
    }
});

其中...概述的部分需要由您定义和实现。但是,该包中的代码已经提供了一个ComposedSplitFunction实现,该实现需要PartitionFunction和PromotionFunction作为输入,其中PartitionFunctions和PromotionFunctions类已经提供了这些实现,它们的工作方式与这里讨论的DistanceFunctionDistanceFunction相同。

 类似资料:
  • 问题内容: 我是Go的新手,在浏览其他一些线程时遇到了以下代码行: 含义是什么?它是否指定将在if条件中分配某些内容(因为err似乎正在发生这种情况)?我在Wiki上找不到这种语法的示例,并且我很好奇它的用途。 问题答案: 因为返回两个值,所以如果需要它们中的任何一个,都必须在某个地方接收这些值。该是一个占位符,基本的意思是“我不关心这个特殊的返回值。” 在这里,我们只关心检查错误,而无需对实际的

  • 问题内容: 我试图一次学习Express库和Node.js。首先,我要看的是Node 函数的细节。 我查看了有关此文档的文档,并在示例文档中找到了一些奇怪的代码: 更具体地说,位。 据我了解,JavaScript中的变量就像其他变量一样。当我们在客户端Web开发上使用它时,它用作文档功能的委托(我认为)。使用节点时分配给什么? 最重要的是,此语法是什么意思? 如果仅仅是对一些函数的引用,那不是等效

  • 所以我有这行代码。它给了我输出[6,28]。你们知道为什么吗?我不知道有人想打印什么样的数字。

  • 在这段代码中,两个连接和断开是什么意思?导致停止,直到终止?

  • 问题内容: 码: 问题答案: 文件模式,写入和二进制。由于您正在编写.jpg文件,因此看起来不错。 但是,如果您应该阅读该jpg文件,则需要使用 更多信息 在Windows上,附加到模式的’b’以二进制模式打开文件,因此也有’rb’,’wb’和’r + b’之类的模式。Windows上的Python区分文本文件和二进制文件。读取或写入数据时,文本文件中的行尾字符会自动更改。对于ASCII文本文件来

  • 问题内容: 任何人都可以确认我是否正确地在下面的方法调用中看到了该参数: 作为对象类型的数组?我不记得以前在Java中见过。 问题答案: 它等效于,但允许调用者一次只指定一个值作为参数,编译器将创建一个数组。所以这个电话: 相当于 有关更多信息,请参见varargs功能的文档(在Java 5中引入)。