不清楚“比较方法违反了其总契约!”在传递比较器中

问题描述 投票:0回答:1

在 Java8 中,我有一个我无法真正更改的算法,它对特定结构进行排序,如下所示:

  • 类别 XXX 中的所有元素都必须位于数组末尾(与顺序无关)
  • 所有其他元素可以有任何顺序

它是这样实现的:

list.sort((o1, o2) -> {
        boolean isXXX1 = "XXX".equals(o1.getCategory());
        boolean isXXX2 = "XXX".equals(o2.getCategory());
        if(isXXX1) {
            return isXXX2 ? 0 : 1;
        } else if(isXXX2) {
            return -1;
        }
        return o1.hashCode() - o2.hashCode();
    });

Hashcode 是由 ReflectionashCode 在 PoJo 对象上创建的,因此我预计不会发生奇怪的冲突。

偶尔,显然是随机的,这段代码会抛出 IllegalArgumentException:比较方法违反了其一般契约!

我尝试对其进行调试,但即使在调试模式下使用相同的数据,它也不会中断。 可能是什么原因?我没有看到任何排序不尊重合同的情况

sorting java-8 timsort
1个回答
0
投票

来自合同

实现者必须确保compare(x, y)==0意味着对于所有z来说sgn(compare(x, z))==sgn(compare(y, z))。

对于您的比较器,如果您有元素 x(XXX, hc:0), y(XXX,hc:5), z(YYY,hc:3),

比较(x,y)== 0

比较(x,z)== 1

比较(y,z)== -1

© www.soinside.com 2019 - 2024. All rights reserved.