我正在尝试创建一个使用相对距离比较的有序地图。然而,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
答案 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());
现在,这将points
与fixedPoint
的距离进行排序。或者,出于效率原因,您可以使用以下事实:当您添加新项目时,该集合已经被排序以插入到正确的位置:
您参考了Comparator
的文档,特别是关系的组理论定义。关键条件是,如果两个项目是equals
,那么它们在比较时必须返回0。然而情况恰恰相反:如果两个项目在比较时返回0,则不一定意味着它们是equals
。在许多情况下,两个项目的顺序是未定义的。一个简单的例子是忽略大小写的字典顺序。在这种情况下,“Foobar”,“foobar”和“FOOBAR”这两个词在命令方面都是“相同的”。
这在文件中被称为“与平等不一致”。例如,SortedSet
的文档说:“即使排序与equals不一致,排序集的行为也是明确定义的;它只是不遵守Set接口的一般契约。”对于Set
的所有实现都不是这样。