当前位置: 首页 > 知识库问答 >
问题:

比较法违反了它的通用契约!Java7比较仪

阙佐
2023-03-14
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.mergeCollapse(TimSort.java:408)
    at java.util.TimSort.sort(TimSort.java:214)
    at java.util.TimSort.sort(TimSort.java:173)
    at java.util.Arrays.sort(Arrays.java:659)
    at java.util.Collections.sort(Collections.java:217)

有人能解释一下为什么我下面的比较器有时候会抛出上面的异常吗?

注意:myObject 中的 id 字段类型为 long。

Collections.sort(objectList, new Comparator<MyObject>() {

    @Override
    public int compare(final myObject myobject1, final MyObject myObject2) {

        return (int)(myObject1.getId() - myObject2.getId());

    }
});

解决方案:

基于@amit的回答

return (int)(Long.compare(myObject1.getId(), myObject2.getId());

共有2个答案

杨志强
2023-03-14

Java7已将Java.util.Arrays中的默认排序算法从 更改为 。sort</code>方法。

< code > Java . util . arrays . sort 和< code > Java . util . collections . sort 使用的(< code >间接)排序算法已被替换。如果新的排序实现检测到违反可比协定的可比,它可能会引发< code > IllegalArgumentException 。

为了向后兼容并从版本6恢复Java行为,请添加新的系统属性java.util.Arrays.useLegacyMergeSort。

详情请参考以下链接-

http://www . Oracle . com/tech network/Java/Java se/compatibility-417013 . html # source

左华灿
2023-03-14

如果ID是绝对值相对较高的整数,您可能会遇到整数溢出,这将导致< code > VERY _ HIGH _ INT-VERY _ LOW _ INT 成为负数。这显然是错误的,并且正在破坏比较者的契约。

使用<code>Integer。compare()(或类似地Long.compare(()Double.compare()…),而不是用减法来避免。

编辑:

具体到这里,问题仍然是整数溢出,当转换一个长值时,其32个LSbs在范围[2^31,2^32)从Longint,这导致它错误地为负数。在ideone中演示。

解决方案是一样的。使用Long.compare()

 类似资料:
  • 我有一个自己的,相对复杂的字符串比较器和一个庞大的字符串列表(~100个字符串,已经尝试减少,但问题不可重现),其中对它们进行排序会产生上述错误尝试使用Java 7排序。我想,规则 可能会被侵犯。找出违反合同的样品的最好方法是什么?

  • 我知道很多答案已经回答了我的问题。在我的代码中,异常说“比较方法违反了它的一般合同”,但我不知道我的比较方法如何违反了它的一般合同。这是我的代码:

  • 我发现了许多与此标题相关的重复问题,但没有一个与我的问题有关,因为我的问题无法通过崩溃追踪。我不断收到有关此标题的许多不同的崩溃。 检查此示例(仅在android 4上发生): 我通过研究发现,这种情况发生在比较/排序时,而忽略了某个条件。同时,在我的代码中,我没有使用文档/示例中提到的比较或排序方法。 非常感谢任何建议。

  • 我制作了一个带有jPanel和JLabel数组的调色板。起初它运行良好,但后来我从 JPanel 中取出了一些其他 jLabels,并添加了一些事件。现在我不断收到此错误: 我试图删除第一次收到此错误后所做的一切,但仍然不断收到它。当我将布局从 GridLayout 更改为其他任何内容时,错误消失了,但代码变得无用。所以我需要网格布局。当我将该 JPanel 中的所有内容移动到另一个 JPanel

  • 偏离变量只是包含以下字段的对象的一个实例: 附言时间对象是来自 Joda-Time 库的 DateTime 实例,TransportType 是包含常量火车、海船、驳船和卡车的枚举。 编辑: 好的,所以我将比较器编辑为以下内容: 但这显然违反了一般契约。我如何让它按时间排序,然后根据它们的其他属性对那些具有相等时间的对象进行排序,只关心它们是否相等?希望这有意义… 编辑:解决方案 谢谢大家回答我的

  • 我有时会得到一个 for 我可以始终如一地抛出此异常,实时数据运行足够长的时间,但我不确定如何解决问题的实际原因。 我的比较仪有什么问题?(具体来说,我违反了合同的哪一部分?)如何在不掩盖异常的情况下修复它? 我使用的是 Java 7,如果不进行重大重写就无法升级。 我可以通过将设置为来掩盖异常,但这不是一个理想的解决方案。 我尝试创建测试来随机生成数据并验证每个合同条件。我无法抛出异常。 我尝试