Java@Collections.sort()避坑

498 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情 >>

5a55b29e06143.jpg

Hello everybody ,很荣幸参与本次掘金日新计划·8月份的更文挑战,今天的宣言是:后端 · 擦屁股是一件很烦心的事情。 今天就简简单单的分享,刚刚遇到的一个问题吧!

  • 问题描述: 使用Collections.sort() , 出现 IllegalArgumentException:Comparison method violates its general contract 异常 !

代码如下 :

    Collections.sort(argCompleteHistory, new Comparator<VghLoyaltyHistoryListElement>(){
       @Override
       public int compare(VghLoyaltyHistoryListElement arg0, VghLoyaltyHistoryListElement arg1) {
       try {
        Date date0 = arg0.getActivityDate();
        Date date1 = arg1.getActivityDate();
        return date0.compareTo(date1);
           /*if(date0.getTime() > date1.getTime()){
             return  1;
           }else {return -1;}*/
         } catch (Exception  e) {
          e.printStackTrace();
         }
        return 0;
      }
    });

这段代码是对 argCompleteHistory 集合通过Collections.sort() 函数进行排序,看上去是没有什么问题。

  • 问题分析: 分析Collections.sort()函数执行过程中的对象排序规则
  1. Collections.sort() 函数中compare(a,b){date0.compareTo(date1)} 方法 实际上 是在对其中这两个对象中的dat属性做比较,其中对比的结果存在三个有效的值[0, 1, -1],
决定
1表示当前对象比要比较的对象大, 往后排
0表示当前对象等于要比较的对象, 位置不变
-1表示当前对象比要比较的对象小, 往前排
  1. Collections.sort()函数有三个排序原则需要满足:

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

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

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

这其中很容易出现数据违反其中的原则,就会抛出 IllegalArgumentException:Comparison method violates its general contract 异常 。

  • 问题总结: Jdk1.8 以上的版本不是很建议继续使用这个Collections.sort()函数,其中jdk1.8以上更新了一些相关地排序函数 : eg:completeHistory.sort(Comparator.comparing(VghLoyaltyHistoryListElement::getActivityDate).reversed());

Comparator.comparing()为正序, Comparator.comparing().reversed()为其倒序排列。 就可以避免Collections.sort()排序中出现的各种异常存在。

今天的日更就到这吧,希望能避免此类排序问题异常的抛出 … 我们下期见!