复现
错误代码如下
Collections.sort(dataList, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 > o2 ? 1 : -1;
}
});
这里看着也没啥问题啊,相同的代码运行在不同手机上为啥有的报错有的不报错呢?根据错误提示Comparison method violates its general contract!去查看源码后找到抛出导致这个错误代码的具体位置
if (len1 == 1) {
assert len2 > 0;
System.arraycopy(a, cursor2, a, dest, len2);
a[dest + len2] = tmp[cursor1];
} else if (len1 == 0) {
throw new IllegalArgumentException("Comparison method violates its general contract!");
} else {
assert len2 == 0;
assert len1 > 1;
System.arraycopy(tmp, cursor1, a, dest, len1);
}
查阅相关资料后发现说这种写法在Java JDK6中没有问题。在Java JDK6以后,Comparator要满足自反性、传递性、对称性,不然Arrays.sort、Collections.sort会报IllegalArgumentException异常。说明:
- 自反性:x,y 的比较结果和y,x的比较结果相反。
- 传递性:x > y,y > z,则x > z。
- 对称性:x = y,则x,z比较结果和y,z比较结果相同。
然而错误写法:o1 > o2 ? 1 : -1,并没有处理相等的情况,所以在实际使用中可能会出现异常。
斗罗小剧场
小舞:哥,这里我有个疑问了,运行的环境都是Java JDK8的,为啥有的手机不会闪退有的手机会闪退呢?
小三:额......这......
小三:小舞,哥现在修为等级还不够,等我魂力到达90级或许可以帮你解决这个问题!!!
总结
根据上面的分析,在Java JDK6以后,Comparator要满足自反性、传递性、对称性。所以正确的写法应该是
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//return o1 - o2或者return o1.compareTo(o2)
return o1.compareTo(o2);
}
});
网友评论