谁能简单地解释一下,为什么这段代码抛出一个异常,“比较方法违反了它的一般契约!”,以及我该如何修复它?
private int compareParents(Foo s1, Foo s2) {
if (s1.getParent() == s2) return -1;
if (s2.getParent() == s1) return 1;
return 0;
}
谁能简单地解释一下,为什么这段代码抛出一个异常,“比较方法违反了它的一般契约!”,以及我该如何修复它?
private int compareParents(Foo s1, Foo s2) {
if (s1.getParent() == s2) return -1;
if (s2.getParent() == s1) return 1;
return 0;
}
当前回答
我也遇到过同样的问题,但我解决了。
//This this your code
private int compareParents(Foo s1, Foo s2) {
if (s1.getParent() == s2) return -1;
if (s2.getParent() == s1) return 1;
return 0;
}
违例是将不同的事物相互比较。
//acceptable
compare between s1.getParent() and s2.getParent()
//acceptable
compare between s1 and s2
//NOT acceptable
compare between s1 and s2.getParent()
//NOT acceptable
compare between s1.getParent() and s2
在我的代码中,我想通过地址的协调来排序。在比较器中,我错误地比较了X和Y,而不是X和X。
//My code:
private void sortBasedOnX(){
//addresses is a list of addresses where each address has X and Y
addresses.sort((o1, o2) -> {
String a = o1.getAddress().getX();
String b = o2.getAddress().getY(); //<-- this is supposed to be getX
return Integer.parseInt(a)-Integer.parseInt(b);
});
}
//acceptable
compare between o1.getAddress().getX() and o1.getAddress().getX()
//acceptable
compare between o1.getAddress().getY() and o1.getAddress().getY()
//NOT acceptable
compare between o1.getAddress().getX() and o1.getAddress().getY()
//NOT acceptable
compare between o1.getAddress().getX() and o1.getAddress()
//NOT acceptable
compare between o1.getAddress().getX() and o1
其他回答
以我为例,我做了如下事情:
if (a.someField == null) {
return 1;
}
if (b.someField == null) {
return -1;
}
if (a.someField.equals(b.someField)) {
return a.someOtherField.compareTo(b.someOtherField);
}
return a.someField.compareTo(b.someField);
我忘记检查的是当a.someField和b.someField都为空时。
编辑虚拟机配置对我很有用。
-Djava.util.Arrays.useLegacyMergeSort=true
你的比较器是不可传递的。
假设A是B的父类,B是C的父类,因为A > B和B > C,那么A > C必须是这样。然而,如果你的比较器在A和C上被调用,它将返回零,这意味着A == C。这违反了契约,因此抛出异常。
库能够检测到这一点并让您知道,而不是表现得不稳定,这是相当不错的。
在compareParents()中满足传递性要求的一种方法是遍历getParent()链,而不是只查看直接祖先。
你不能像这样比较对象数据:s1.getParent() == s2 -这将比较对象引用。你应该重写Foo类的equals函数然后像这样比较它们s1.getParent()。equals(s2)
如果compareParents(s1, s2) == -1,则期望compareParents(s2, s1) == 1。对于你的代码,这并不总是正确的。
具体来说,如果s1. getparent () == s2 && s2. getparent () == s1。 这只是可能出现的问题之一。