【问题标题】:Comparison method violates its general contract Exception比较方法违反其一般合同异常
【发布时间】:2013-04-18 08:58:15
【问题描述】:

下面是导致异常的代码块,

代码:

Collections.sort( arrayList, new Comparator() 
{
    public int compare( Object o1, Object o2 )
    {
        TypeAdapterSort tas1 = ( TypeAdapterSort ) o1;
        TypeAdapterSort tas2 = ( TypeAdapterSort ) o2;
        if ( tas1.order < tas2.order )
            return -1;
        else
            return 1;
    }
} );

例外:

java.lang.IllegalArgumentException: Comparison method violates its general contract!
                at java.util.TimSort.mergeLo(TimSort.java:747)
                at java.util.TimSort.mergeAt(TimSort.java:483)
                at java.util.TimSort.mergeForceCollapse(TimSort.java:426)
                at java.util.TimSort.sort(TimSort.java:223)
                at java.util.TimSort.sort(TimSort.java:173)
                at java.util.Arrays.sort(Arrays.java:659)
                at java.util.Collections.sort(Collections.java:217)

当我运行与独立程序相同的代码时,问题永远不会发生。这里的比较器有什么问题?有没有办法在独立代码中重现该问题?

此问题仅在 Java 1.7 上出现,因为 Arrays.sort 和 Collections.sort 的实现发生了变化。如何更改上述代码以避免该问题?另外,如何在独立代码中重现此问题?

【问题讨论】:

标签: java collections comparator


【解决方案1】:

你需要在相等的对象上返回 0。

        if ( tas1.order < tas2.order ){
            return -1;
        } else if ( tas1.order == tas2.order ){
            return 0;
        } else {
            return 1;
        }

你可以阅读here更多

【讨论】:

  • 但是,为什么当作为独立程序运行时,实例变量顺序的值保持不变时,问题没有重现?
  • compare 必须是可传递的。你的代码不是。因此,它不会错误地工作,而是向您说明您的代码有错误。我认为这是一种非常好的行为。
  • @baraky 你可能希望写tas1.order == tas2.order,你肯定错过了双“=”而不是......分配;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多