Timsort排序异常现象

Timsort排序异常现象异常类型 java lang IllegalArgum Comparisonme nbsp 分析 线上非必现 偶发概率很小 java7 开始引入了 Timsort 的排序算法 是稳定的 nlogn 复杂度 表现效果比快排要好 异常的原因是实现的 compare 排序算法不够严谨导致 需要对非法的比较对象进行更

异常类型:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
 
分析:线上非必现,偶发概率很小;
java7开始引入了Timsort
的排序算法,是稳定的nlogn复杂度,表现效果比快排要好。
异常的原因是实现的compare排序算法不够严谨导致
,需要对非法的比较对象进行更严谨的判断;
 
Timsort算法规则:
JDK7以后,实现Comparable接口后,要满足一下三个特性:
1) 自反性:x,y 的比较结果和 y,x 的比较结果相反。
2) 传递性:x>y,y>z,则 x>z。
3) 对称性:x=y,则 x,z 比较结果和 y,z 比较结果相同。
(不严谨写法,违反了该条规则)
 
解决方法1:使用jdk6较宽松的规则;
缺点:使用不了Timsort算法:
System.setProperty(“java.util.Arrays.useLegacyMergeSort”, “true”); 
 
解决方法2:调整比较方法:(建议该方法)
缺点:需要根据具体情况调整比较逻辑;
模拟了一个线上异常概率高的示例及参考解决方法,如下:

import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Random; import org.apache.commons.lang3.StringUtils; public class Test { public static void sortMessage(List 
   
     list) { Collections.sort(list, new Comparator 
    
      () { public int compare(String arg1, String arg2) { / * 不严谨写法 */ // if(StringUtils.isBlank(arg1) || StringUtils.isBlank(arg2)) { // return 0; // } / * 优化后写法 */ if(StringUtils.isBlank(arg1) ) { if(StringUtils.isBlank(arg2)) { return 0; }else { return -1; } }else if(StringUtils.isBlank(arg2)){ return 1; } return arg1.compareTo(arg2); } }); } public static void main(String[] args) throws InterruptedException { List 
     
       list = new ArrayList 
      
        (); Random random = new Random(); for(int i=10000;i>0;i--) { if(i%5000 != 0) { list.add(random.nextInt(1000)+""); }else { list.add(""); } } sortMessage(list); } } 
       
      
     
   





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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215355.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午2:06
下一篇 2026年3月18日 下午2:07


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号