前言
java Collections.sort 排序失效?为什么会排序失效呢?
需求和问题
需求:获取指定文件夹下的所有文件,并且按照修改时间顺序从大到小排序,如果修改时间相同,则按照创建时间从大到小排序
// 输入list, 遍历文件夹产生list文件数组
List<MyFile> list =..... 文件
// 对文件集合进行排序Collections.sort(list , (a, b) -> {int t = (int) (b.getLastupdateTime() - a.getLastupdateTime());if (t != 0) {return t > 0 ? 1 : -1;}Long at = a.getCreateTime();at = null == at ? 0 : at;Long bt = b.getCreateTime();bt = null == bt ? 0 : bt;if (bt - at == 0) {return 0;}return bt - at > 0 ? 1 : -1;});
输出结果发现明明按照修改时间排序,为什么顺序不符合预期?
原因分析:
由于 lastupdateTime 是long类型
所以强制转换的时候就可能发生问题,例如以下代码,a>b 没问题,但是a-b变成再经过int强转时变成了负数。
long a = Integer.MAX_VALUE + Integer.MAX_VALUE + 2;long b = Integer.MAX_VALUE + 1;System.out.println(a > b); //trueSystem.out.println((int) (a - b)); //-2147483648
而上面的sort排序也就存在同样问题,直接将两个long类型的差值强制转换,就会出现虽然a大于b,但是结果a减b是负数,导致排序错误。
因此在进行排序时,我们不能强制将大于int长度的数值强制转换为int
正确的做法应该是三目运算判断,避免强转类型影响结果。
Collections.sort(list , (a, b) -> {long t = b.getLastupdateTime() - a.getLastupdateTime();if (t != 0) {return t > 0 ? 1 : -1;}Long at = a.getCreateTime();at = null == at ? 0 : at;Long bt = b.getCreateTime();bt = null == bt ? 0 : bt;if (bt - at == 0) {return 0;}return bt - at > 0 ? 1 : -1;});