使用Collections.sort()和自定义比较器时,我收到错误
java.lang.IllegalArgumentException: Comparison method violates its general contract!
在谷歌搜索这个错误之后,我看到几个解释说如果comapare(a,b)给我-1并且比较(b,a)也给我-1然后我会看到这个错误。
我不明白为什么比较发生两次?
答案 0 :(得分:0)
JavaDoc of Comparable's compareTo()
实现者必须确保所有x和y的sgn(x.compareTo(y))== -sgn(y.compareTo(x))。 (这意味着如果y.compareTo(x)抛出异常,x.compareTo(y)必须抛出异常。)
实现者还必须确保关系是传递的:(x.compareTo(y)> 0& y.compareTo(z)> 0)意味着x.compareTo(z)> 0。 / p>
最后,对于所有z,实现者必须确保x.compareTo(y)== 0意味着sgn(x.compareTo(z))== sgn(y.compareTo(z))。
简单来说,它意味着以下内容:
x.compareTo(y)
抛出异常,y.compareTo(x)
也应该抛出异常。x > y
和y > z
,则x > z
x.compareTo(y) == 0
,则x.compareTo(z)
和y.compareTo(z)
应具有相同的符号。简而言之:如果a == b
,则b == a
。如果没有,那你违反了合同。
答案 1 :(得分:0)
从Java 1.8开始,Collections.sort(..)
将工作交给List#sort()
,Arrays.sort(..)
将工作交给TimSort
,ATable
将工作交给课程ITable<ARow>
。 Here's a link to the API and code used for that algorithm.
它非常混乱和复杂(有充分的理由 - 优化排序算法很重要),但足以说它从不保证(或甚至建议)每对元素只进行一次比较。它保证最多O(n * logn)比较,但不是它们将是唯一的比较。