Collections.sort()引发比较方法违反了它的一般约定!例外 [英] Collections.sort() throws Comparison method violates its general contract! exception
问题描述
我正在尝试对List对象进行排序,并且抛出此异常(仅适用于大型列表)
I'm trying to sort a List<> object and I get this exception thrown (for large lists only though)
排序代码:
List<FinalSentence> sentenceList = finalRepresentation.getSentences();
Collections.sort(sentenceList); // <=== EXCEPTION THROWN HERE!!!
FinalSentence类标题:
FinalSentence class header:
public class FinalSentence implements Comparable<FinalSentence>{...}
compareTo ()实现:
compareTo() implementation:
@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,并不重要。
for a small list (less than 50 elements) it works. for a large list (it's supposed to work with those as well) it throws this exception. The instance type of the List is ArrayList, not that it should matter.
我不知道如何深入了解这一点。列表已满,元素是同一类型(那里没有多态性),但是对于大型列表,我却得到了这个怪异的例外。
I have no idea how to get to the bottom of this. The list is full, the elements are of the same type (no polymorphism there) and yet I get this weird exception for large lists.
有什么想法吗?
谢谢!
推荐答案
Double.compare(score, o.score)
解决了该问题。我的猜测是±0
s或 NaN
s有问题。实际上,如果您查看 Double.compare()
的来源,您会发现它比您想象的要复杂一些,并专门处理以下情况:
fixed the issue. My guess is that there was either a problem with ±0
s or NaN
s. In fact, if you look at the source of Double.compare()
, you will find that it's slightly more complicated than you might think, and treats these cases specifically:
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 }
(源)
道德是:比较双打时要小心! :)
Moral is: be careful when comparing doubles! :)
参考:
这篇关于Collections.sort()引发比较方法违反了它的一般约定!例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!