具有相对距离的Java比较器

时间:2015-02-14 23:31:33

标签: java dictionary data-structures distance comparator

我正在尝试创建一个使用相对距离比较的有序地图。然而,ConcurrentSkipListMap(我现在正在使用它)的方式解释了Comparator的比较使得比较不可能的相对距离。是否有任何数据结构允许映射像键值操作和相对排序?

当我说相对比较时,我的意思是两个值不能直接比较,但必须用参考点来看。想想欧几里德距离。

编辑:

例如:当比较二进制数0011和1100时,我想说一个比另一个大于汉明距离(两个数的xor中的1位数,相当于超立方体中两个节点之间的距离)图),显然我需要一个参考点才能比较距离,所以我选择0000作为参考。从0011到0000的距离是2,从1100到0000的距离是2,但1100不等于0011.我想说它们具有相同的相对距离,但不相等。最终将生成这些数字的排序列表。对于参考0000,按升序排列,我们可能有1000,0100,1100,1001,1001,1110,1101,1111。

EDIT2,为什么我不能使用比较器:

  

此总订单的商是:          {(x,y)使得c.compare(x,y)== 0}。

     

紧跟比较合同后,商是S上的等价关系,强制排序是S上的总顺序。当我们说c对S施加的顺序与等于一致时,我们意味着排序的商是由对象的equals(Object)方法定义的等价关系:        {(x,y)使得x.equals(y)}。

http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

2 个答案:

答案 0 :(得分:3)

当距离相同时,您可以通过进一步比较来区分与参考编号具有相同距离的实例。例如,假设您将数字表示为Integer s:

    public int compare(Integer i1, Integer i2) {
        Integer r1 = hammingDistanceToReference(i1);
        Integer r2 = hammingDistanceToReference(i2);

        if (!r1.equals(r2))
            return r1.compareTo(r2);

        return i1.compareTo(i2);
    }

这样,与参考号具有不同汉明距离的数字将被正确排序,而具有相同汉明距离的数字也将被完全排序。

答案 1 :(得分:-2)

一些Set实现允许比较器与equals不一致。如果ConcurrentSkipListMap没有,那么您的选项是使用一个或使用无序集合,然后使用Collection.sort在插入时手动对其进行排序。

以下是创建Comparator(与equals不一致)的示例:

class Point {
    int distanceTo(Point other) {
        ...
    }

    Comparator<Point> distanceComparator() {
        return (point1, point2) -> distanceTo(point1) - distanceTo(point2);
    }
}

List<Point> points;
Point fixedPoint;
Collections.sort(points, fixedPoints.distanceComparator());

现在,这将pointsfixedPoint的距离进行排序。或者,出于效率原因,您可以使用以下事实:当您添加新项目时,该集合已经被排序以插入到正确的位置:

您参考了Comparator的文档,特别是关系的组理论定义。关键条件是,如果两个项目是equals,那么它们在比较时必须返回0。然而情况恰恰相反:如果两个项目在比较时返回0,则不一定意味着它们是equals。在许多情况下,两个项目的顺序是未定义的。一个简单的例子是忽略大小写的字典顺序。在这种情况下,“Foobar”,“foobar”和“FOOBAR”这两个词在命令方面都是“相同的”。

这在文件中被称为“与平等不一致”。例如,SortedSet的文档说:“即使排序与equals不一致,排序集的行为也是明确定义的;它只是不遵守Set接口的一般契约。”对于Set的所有实现都不是这样。