Java Collections自定义排序结果解析:为何输出指定序列?
Java代码排序逻辑解析
代码展示
List<Integer> list = new ArrayList<>(); for(int i = 0 ; i <= 8 ; i ++){ list.add(i+1); } Collections.sort(list,(a, b)-> (a%b==0)?1 : (a%b==1)?-1 :0 ); list.forEach(System.out::println);
排序规则拆解
这段代码用Lambda实现了自定义排序逻辑,规则如下:
- 若
a % b == 0(a能被b整除),返回1:说明a的排序优先级低于b,b会排在a前面 - 若
a % b == 1(a除以b余1),返回-1:说明a的排序优先级高于b,a会排在b前面 - 其他情况返回
0:a和b的相对顺序保持不变
输出结果原因分析
初始列表为 [1,2,3,4,5,6,7,8,9],结合规则和实际输出逐一说明:
- 1排在最前面:任何整数除以1的余数都是0,其他元素x和1比较时,
compare(x,1)返回1,x优先级低于1,因此所有元素都排在1之后。 - 4在3前面:
4%3=1,compare(4,3)返回-1,4优先级高于3,排在前面。 - 3在2前面:
3%2=1,compare(3,2)返回-1,3优先级高于2,排在前面。 - 5、7在2前面:5、7和4、3比较时,余数既不是0也不是1,返回
0,保留初始顺序(4→3→5→7);同时5%2=1、7%2=1,compare(5,2)、compare(7,2)返回-1,5、7优先级高于2,排在2前面。 - 6在2后面:
6%2=0,compare(6,2)返回1,6优先级低于2,排在2后面;和5、7比较时余数无特殊情况,顺序不变。 - 9、8的位置:这个自定义排序逻辑违反了Comparator的传递性契约(比如
compare(4,3)=-1、compare(3,2)=-1,但compare(4,2)=1,逻辑矛盾),导致排序结果依赖JDK内置排序算法(如TimSort)的具体执行过程,最终9排在6之后、8排在9之后。
关键问题
该Comparator不合法,因为它不满足排序逻辑必须遵循的传递性规则,排序结果可能因JDK版本或环境不同而变化。
内容的提问来源于stack exchange,提问作者Abhishek Pandey
相关产品推荐
相关产品推荐

