2025年“Comparison method violates its general contract!”问题原因及解决办法

“Comparison method violates its general contract!”问题原因及解决办法开发中踩到的坑 通过 arraylist sort 对元素进行排序 测试阶段没发现 上线后不久报了这个错误 Comparison method violates its general contract 查了一些资料 下面总结一下 先贴下出错的代码 stus sort o1 o2 gt if

大家好,我是讯享网,很高兴认识大家。

开发中踩到的坑。通过arraylist.sort对元素进行排序,测试阶段没发现,上线后不久报了这个错误。“Comparison method violates its general contract!”。查了一些资料,下面总结一下。先贴下出错的代码:

stus.sort((o1, o2) -> { 
    if(o1 == null || o2 == null || o1 == o2) { 
    return 0; } return o1.age - o2.age; }); 

讯享网

在这里插入图片描述
讯享网

看起来没什么问题,但是却报了一个错,“比较方法违反其一般合同”。

在 JDK7 版本以上,Comparator 要满足自反性,传递性,对称性,不然 Arrays.sort,Collections.sort
会报 IllegalArgumentException 异常。

自反性:当 两个相同的元素相比时,compare必须返回0,也就是compare(o1, o1) = 0;

反对称性:如果compare(o1,o2) = 1,则compare(o2, o1)必须返回符号相反的值也就是 -1;

传递性:如果 a>b, b>c, 则 a必然大于c。也就是compare(a,b)>0, compare(b,c)>0, 则compare(a,c)>0

回到上面的例子,假设存在三个元素:stu1, null,stu2,则
compare(stu1, null)= 0,
compare(null, stu2) = 0,
compare(stu1,stu2) =1 很明显违反了传递性原则。

可以改成 为

讯享网stus.sort((o1, o2) -> { 
    if(o1 == null) { 
    if(o2 == null) { 
    return 0; } return 1; } if(o2 == null) { 
    return -1; } return o1.age - o2.age; }); 

再举个例子,下面的例子是用于比较字符串的长度(参考博客:https://stackoverflow.com/questions//comparison-method-violates-its-general-contract)

if ( one.length() == 0 ) { 
    return 1; // empty string sorts last } if ( two.length() == 0 ) { 
    return -1; // empty string sorts last  } return one.compareToIgnoreCase( two ); 

这里违反了 自反性,compare(“”, “”) = 1, 正确的结果应该是返回 0,所以会报错。
原来的代码可以修改为:

讯享网if ( one.length() == 0 ) { 
    if ( two.length() == 0 ) { 
    return 0; // BOth empty - so indicate } return 1; // empty string sorts last } if ( two.length() == 0 ) { 
    return -1; // empty string sorts last  } return one.compareToIgnoreCase( two ); 
小讯
上一篇 2025-01-04 23:32
下一篇 2025-04-11 17:55

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/50876.html