【问题标题】:buildin compareTo: Comparison method violates its general contractbuildin compareTo:比较方法违反了它的一般约定
【发布时间】:2016-07-25 10:57:35
【问题描述】:

我目前正在努力用 Java 对集合进行排序。我收到错误消息“比较方法违反其一般合同”。我也理解这个错误消息,但我(主要)使用的是 Long 类型的 buildin compareTo-Method。所以我不知道,在这种情况下 sort 方法仍然违反合同。这是我的代码:

@Override
public int compareTo(DataAge another) {
    if(this == null || another == null)
        return 0;

    Long a = new Long(this.getAge());
    Long b = new Long(another.getAge());
    return a.compareTo(b);
}

这里是错误:

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

at java.util.ComparableTimSort.mergeLo(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 dd.GMAAnalyzer.sortData(Analyzer.java:158)

【问题讨论】:

  • 注意:this == null 总是假的。

标签: java sorting collections


【解决方案1】:

假设nulls 是允许的,你的方法的逻辑是不正确的,因为null 比较等于任何东西。这是错误的,因为它将与多个彼此不相等的事物进行比较,从而破坏了传递性。

要解决这个问题,决定nulls应该排在前面还是排在其他数字后面,并添加一个单独的null比较(this不能等于null,所以你不需要比较)。

if(another == null)
    return 1; // If you want nulls in the back, return -1

【讨论】:

    【解决方案2】:

    来自Comparable的Javadoc:

    请注意,null 不是任何类的实例,即使 e.equals(null) 返回 false,e.compareTo(null) 也应该抛出 NullPointerException

    另外,您不需要创建 Long 实例:

    return Long.compare(this.getAge(), another.getAge());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多