携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情 >>
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()函数执行过程中的对象排序规则
- Collections.sort() 函数中compare(a,b){date0.compareTo(date1)} 方法 实际上 是在对其中这两个对象中的dat属性做比较,其中对比的结果存在三个有效的值[0, 1, -1],
| 值 | 决定 |
|---|---|
| 1 | 表示当前对象比要比较的对象大, 往后排 |
| 0 | 表示当前对象等于要比较的对象, 位置不变 |
| -1 | 表示当前对象比要比较的对象小, 往前排 |
-
Collections.sort()函数有三个排序原则需要满足:
-
自反性:当 两个相同的元素相比时,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 。
这其中很容易出现数据违反其中的原则,就会抛出 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()排序中出现的各种异常存在。
今天的日更就到这吧,希望能避免此类排序问题异常的抛出 … 我们下期见!