java – Collections.sort()throws比较方法违反了它的一般合同!例外

我正在尝试排序列表<>对象,我得到这个异常抛出(仅对于大型列表)

排序代码:

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,而不是它应该是重要的.

我不知道如何达到这个底线.列表是完整的,元素是相同的类型(没有多态性),但我得到这个奇怪的异常大列表.

有任何想法吗?

先谢谢!

最佳答案
根据OP’s comment,my suggestion使用

Double.compare(score, o.score)

解决了问题.我的猜测是有0或者NaNs有问题.实际上,如果你看看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)

道德是:比较双打时要小心! 🙂

参考:

> Double.compare()

转载注明原文:java – Collections.sort()throws比较方法违反了它的一般合同!例外 - 代码日志