关于lamda的sort多字段排序

今天遇到个需求,要按照两个字段排序(一个倒序一个正序),乍眼一看用sql(order by)就ok了,结果实际情况不是想象那样,那个数据不是直接sql能查出的,需要在代码中做一些处理。

先给上个栗子:

@Data
    @AllArgsConstructor
    @ToString
    public static class Student {
        private Integer age;
        private Integer score;
    }

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            Student student = new Student(RandomUtil.randomInt(1, 5), RandomUtil.randomInt(1, 5));
            studentList.add(student);
        }

        studentList = studentList.stream().sorted(Comparator.comparing(Student::getAge).thenComparing(Student::getScore)).collect(Collectors.toList());
        System.out.println("结果1:age正序 score正序");
        studentList.stream().forEach(System.out::println);

        studentList = studentList.stream().sorted(Comparator.comparing(Student::getAge).reversed().thenComparing(Student::getScore)).collect(Collectors.toList());
        System.out.println("结果2:age倒序 score正序");
        studentList.stream().forEach(System.out::println);

        studentList = studentList.stream().sorted(Comparator.comparing(Student::getAge).reversed().thenComparing(Student::getScore).reversed()).collect(Collectors.toList());
        System.out.println("结果3:age正序 score倒序");
        studentList.stream().forEach(System.out::println);
    }

打印结果:

结果1:age正序 score正序
IndexController.Student(age=1, score=2)
IndexController.Student(age=1, score=3)
IndexController.Student(age=2, score=1)
IndexController.Student(age=2, score=2)
IndexController.Student(age=4, score=3)
IndexController.Student(age=4, score=3)
结果2:age倒序 score正序
IndexController.Student(age=4, score=3)
IndexController.Student(age=4, score=3)
IndexController.Student(age=2, score=1)
IndexController.Student(age=2, score=2)
IndexController.Student(age=1, score=2)
IndexController.Student(age=1, score=3)
结果3:age正序 score倒序
IndexController.Student(age=1, score=3)
IndexController.Student(age=1, score=2)
IndexController.Student(age=2, score=2)
IndexController.Student(age=2, score=1)
IndexController.Student(age=4, score=3)
IndexController.Student(age=4, score=3)

其实这里前两个结果都很好理解,就是第三个结果有点不按正常套路出牌。

reversed()这个方法的意思按照前两个运行结果就是反序,可是在第三个结果中age正序、score倒序,其实看到这里也大概理解这里其中的奥义了,就是作用域不同。reversed()是将前面所有字段排序在进行颠倒排序一次,所以在这里让age倒序又倒序不就正序了(正如负负得正)!


版权声明:本文为qq_41611676原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。