我正在尝试对List<>进行排序对象和我抛出此异常(仅适用于大型列表)
排序代码:
List<FinalSentence> sentenceList = finalRepresentation.getSentences();
Collections.sort(sentenceList); // <=== EXCEPTION THROWN HERE!!!
FinalSentence类标题:
public class FinalSentence implements Comparable<FinalSentence>{...}
compareTo()实现:
@Override
public int compareTo(FinalSentence o) {
if (this == o) {
return 0;
}
if (this.score > o.score) {
return 1;
}
if (this.score < o.score) {
return -1;
}
return 0;
}
这是例外:
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeHi(Unknown Source)
at java.util.ComparableTimSort.mergeAt(Unknown Source)
at java.util.ComparableTimSort.mergeCollapse(Unknown Source)
at java.util.ComparableTimSort.sort(Unknown Source)
at java.util.ComparableTimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at feature.finalRepresentation.Summarizer.summarize(Summarizer.java:30)
at driver.Driver.main(Driver.java:114)
对于一个小列表(少于50个元素)它的工作原理。对于一个大的列表(它应该也适用于那些)它会引发这个异常。 List的实例类型是ArrayList,而不是它应该重要。
我不知道如何深入了解这一点。列表已满,元素属于同一类型(那里没有多态)但是我得到了大型列表的奇怪异常。
有什么想法吗?
提前致谢!!!
答案 0 :(得分:18)
根据OP's comment,my suggestion使用
Double.compare(score, o.score)
解决了这个问题。我的猜测是±0
s或NaN
s有问题。事实上,如果你看一下Double.compare()
的来源,你会发现它比你想象的要复杂一点,并特别对待这些案例:
958 public static int compare(double d1, double d2) {
959 if (d1 < d2)
960 return -1; // Neither val is NaN, thisVal is smaller
961 if (d1 > d2)
962 return 1; // Neither val is NaN, thisVal is larger
963
964 long thisBits = Double.doubleToLongBits(d1);
965 long anotherBits = Double.doubleToLongBits(d2);
966
967 return (thisBits == anotherBits ? 0 : // Values are equal
968 (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
969 1)); // (0.0, -0.0) or (NaN, !NaN)
970 }
(source)
道德是:比较双打时要小心! :)
<强>参考:强>
答案 1 :(得分:4)
如果你违反了及物性规则,就会发生这种情况。如果A> B且B> C,则C> A打破合同
答案 2 :(得分:-4)
你不是说打字:
if (this.score == o.score) {
return 0;
}
而不是:
if (this == o) {
return 0;
}