Stream流sorted的多级排序问题(巨坑)

前言

之前在给一个List集合中对象进行多属性排序,比如先根据对象中的A属性正序排序,若两个对象的A属性值相同,再根据对象的B属性进行正序排序。这种排序在实际开发中比较常见,但是这里面有个坑。

举个例子

先初始化一个学生集合

        List studentArrayList = new ArrayList<>();studentArrayList.add(new Student("张三", 20, 34));studentArrayList.add(new Student("李四", 20, 35));studentArrayList.add(new Student("王五", 22, 34));studentArrayList.add(new Student("丁飞", 21, 23));studentArrayList.add(new Student("曹海", 22, 23));studentArrayList.add(new Student("徐风", 24, 234));

学生类如下

public class Student {private String name;private Integer age;private Integer testScore;public Student(String name, Integer age, Integer testScore) {this.name = name;this.age = age;this.testScore = testScore;}//省略set,get方法
}

如果我们要先根据学生年龄倒序排,再根据学生考试成绩倒序排,很多人可以直接写下这样的排序代码

List studentArraySortList = studentArrayList.stream().sorted(Comparator.comparingInt(Student::getAge).reversed(). thenComparingInt(Student::getTestScore).reversed()).collect(Collectors.toList());

运行结果如下

[姓名=李四,年龄:20分数:35, 姓名=张三,年龄:20分数:34, 姓名=丁飞,年龄:21分数:23,姓名=王五,年龄:22分数:34, 姓名=曹海,年龄:22分数:23, 姓名=徐风,年龄:24分数:234]

很明显,这不是我们预期的效果

如何正确实现多级排序

我们先来看看reversed()方法的方法说明

 大致意思事说在当前的比较器基础上运行新的比较器。

 这里的reversed是运用于Comparator.comparingInt(Student::getAge).reversed().
thenComparingInt(Student::getTestScore)而不是thenComparingInt(Student::getTestScore),这样是不是很好理解了。所以我们要想先根据学生年龄倒序排,再根据学生考试成绩倒序排,应该这样写

List studentArraySortList = studentArrayList.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTestScore).reversed()).collect(Collectors.toList());

感兴趣的小伙伴可以测试下四种写法,对比下运行结果,加深理解


//先根据age正序排,再根据testScore正序排
studentArrayList.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTestScore)).collect(Collectors.toList()).forEach(System.out::println);//先根据age倒序排,再根据testScore正序排
studentArrayList.stream().sorted(Comparator.comparingInt(Student::getAge).reversed().thenComparingInt(Student::getTestScore)).collect(Collectors.toList()).forEach(System.out::println);//先根据age倒序排,再根据testScore倒序排
studentArrayList.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTestScore).reversed()).collect(Collectors.toList()).forEach(System.out::println);//先根据age正序排,再根据testScore倒序排
studentArrayList.stream().sorted(Comparator.comparingInt(Student::getAge).reversed().thenComparingInt(Student::getTestScore).reversed()).collect(Collectors.toList()).forEach(System.out::println);


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部