n00*_*ter 179 java comparator
有人可以用简单的语言解释我,为什么这个代码会抛出异常,"比较方法违反了它的一般合同!",我该如何修复它?
private int compareParents(Foo s1, Foo s2) {
if (s1.getParent() == s2) return -1;
if (s2.getParent() == s1) return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
NPE*_*NPE 249
你的比较器不是传递性的.
让我们A
成为父母B
,并B
成为她们的父母C
.由于A > B
和B > C
,那么它必须是该案件A > C
.但是,如果在A
和上调用比较器C
,它将返回零,这意味着A == C
.这违反了合同,因此抛出异常.
图书馆检测到这个并让你知道,而不是表现得不正常,这是相当不错的.
满足传递性要求的一种方法compareParents()
是遍历getParent()
链而不是仅仅查看直接的祖先.
you*_*786 36
只是因为这是我在谷歌搜索这个错误时得到的,我的问题是我有
if (value < other.value)
return -1;
else if (value >= other.value)
return 1;
else
return 0;
Run Code Online (Sandbox Code Playgroud)
对value >= other.value
应(显然)实际上是value > other.value
让你可以实际上等于对象返回0.
小智 22
违反合同通常意味着比较器在比较对象时没有提供正确或一致的值.例如,您可能希望执行字符串比较并强制将空字符串排序到最后:
if ( one.length() == 0 ) {
return 1; // empty string sorts last
}
if ( two.length() == 0 ) {
return -1; // empty string sorts last
}
return one.compareToIgnoreCase( two );
Run Code Online (Sandbox Code Playgroud)
但是这忽略了一个和两个都是空的情况 - 在这种情况下,返回错误的值(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 );
Run Code Online (Sandbox Code Playgroud)
Ali*_*zan 11
即使你的compareTo在理论上保持传递性,有时候微妙的错误会让事情变得混乱......例如浮点运算错误.它发生在我身上.这是我的代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
传递属性显然是成立的,但由于某种原因,我得到了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;
}
Run Code Online (Sandbox Code Playgroud)
在我们的情况下得到了这个错误,因为我们不小心翻了s1和s2的比较顺序.所以要小心.这显然比以下更复杂,但这是一个例子:
s1 == s2
return 0;
s2 > s1
return 1;
s1 < s2
return -1;
Run Code Online (Sandbox Code Playgroud)
小智 6
编辑 VM 配置对我有用。
-Djava.util.Arrays.useLegacyMergeSort=true
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
181367 次 |
最近记录: |