具有自定义比较器的Collections.sort()是否比较(a,b)和比较(b,a)每对(a,b)

时间:2016-03-29 17:45:50

标签: java collections comparator

使用Collections.sort()和自定义比较器时,我收到错误

java.lang.IllegalArgumentException: Comparison method violates its general contract!

在谷歌搜索这个错误之后,我看到几个解释说如果comapare(a,b)给我-1并且比较(b,a)也给我-1然后我会看到这个错误。

我不明白为什么比较发生两次?

2 个答案:

答案 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 > yy > 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(..)将工作交给TimSortATable将工作交给课程ITable<ARow>Here's a link to the API and code used for that algorithm.

它非常混乱和复杂(有充分的理由 - 优化排序算法很重要),但足以说它从不保证(或甚至建议)每对元素只进行一次比较。它保证最多O(n * logn)比较,但不是它们将是唯一的比较。