有没有人能简单地解释一下,为什么这段代码会抛出一个异常,“比较方法违反了它的常规契约!”,我该如何修复它?
private int compareParents(Foo s1, Foo s2) {
if (s1.getParent() == s2) return -1;
if (s2.getParent() == s1) return 1;
return 0;
}
发布于 2012-07-24 05:14:55
只是因为这是我在谷歌上搜索这个错误时得到的,我的问题是我有
if (value < other.value)
return -1;
else if (value >= other.value)
return 1;
else
return 0;
value >= other.value
应该(显然)实际上是value > other.value
,这样你就可以用相等的对象实际返回0。
发布于 2013-09-27 09:23:27
违反契约通常意味着比较器在比较对象时没有提供正确或一致的值。例如,您可能希望执行字符串比较,并使用以下命令强制空字符串排序到末尾:
if ( one.length() == 0 ) {
return 1; // empty string sorts last
}
if ( two.length() == 0 ) {
return -1; // empty string sorts last
}
return one.compareToIgnoreCase( two );
但这忽略了1和2都为空的情况-在这种情况下,返回错误的值(1而不是0来显示匹配),比较器将其报告为违规。它应该写成:
if ( one.length() == 0 ) {
if ( two.length() == 0 ) {
return 0; // BOth empty - so indicate
}
return 1; // empty string sorts last
}
if ( two.length() == 0 ) {
return -1; // empty string sorts last
}
return one.compareToIgnoreCase( two );
发布于 2015-11-28 20:11:56
即使你的compareTo在理论上保持传递性,有时细微的bug也会把事情搞砸……例如浮点算术错误。这事发生在我身上。这是我的代码:
public int compareTo(tfidfContainer compareTfidf) {
//descending order
if (this.tfidf > compareTfidf.tfidf)
return -1;
else if (this.tfidf < compareTfidf.tfidf)
return 1;
else
return 0;
}
传递性属性显然是成立的,但出于某种原因,我得到了IllegalArgumentException。事实证明,由于浮点算术中的微小错误,导致传递属性在不应该中断的地方发生舍入错误!所以我重写了代码来考虑真正的细微差别0,它起作用了:
public int compareTo(tfidfContainer compareTfidf) {
//descending order
if ((this.tfidf - compareTfidf.tfidf) < .000000001)
return 0;
if (this.tfidf > compareTfidf.tfidf)
return -1;
else if (this.tfidf < compareTfidf.tfidf)
return 1;
return 0;
}
https://stackoverflow.com/questions/8327514
复制相似问题