Java-Stream — как применить сортировку при использовании Collector groupingBy

Я использую Collectors.groupingBy для группировки объектов в список. Примеры следующие:

public class Test {
    public static void main(String[] args) {
        Student student1 = new Student(98,"man","CHEN",20);
        Student student2 = new Student(100,"man","PETER",20);
        Student student3 = new Student(100,"man","TMAC",21);
        ArrayList<Student> list = Lists.newArrayList(student1, student2, student3);

        Map<Integer, List<StudentDTO>> map = list.stream()
            .collect(Collectors.groupingBy(Student::getAge,
                Collectors.mapping(e -> new StudentDTO(e.getScore(), e.getName()),
                    Collectors.toList())
            ));

        System.out.println(map);
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Student {
        private Integer score;
        private String sex;
        private String name;
        private Integer age;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class StudentDTO {
        private Integer score;
        private String name;
    }

}

Вывод:

{20=[Test.StudentDTO(score=98, name=CHEN),
     Test.StudentDTO(score=100, name=PETER)],
 21=[Test.StudentDTO(score=100, name=TMAC)]}

Но моя цель — отсортировать StudentDTO по score, используя Comparator.comparing с потоками. Как я могу этого добиться?

Желаемый результат:

{20=[Test.StudentDTO(score=100, name=PETER),
     Test.StudentDTO(score=98, name=CHEN)],
 21=[Test.StudentDTO(score=100, name=TMAC)]}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
105
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Чтобы отсортировать каждый список StudentDTO по score в порядке убывания, вы можете использовать следующий компаратор:

Comparator.comparingInt(StudentDTO::getScore).reversed()

А чтобы применить сортировку при сборе результата, вы можете использовать сборщик collectAndThen() в качестве нижестоящего по отношению к groupingBy()

List<Student> students = List.of(student1, student2, student3);

Map<Integer, List<StudentDTO>> map = students.stream()
    .collect(Collectors.groupingBy(
        Student::getAge,
        Collectors.collectingAndThen(
            Collectors.mapping(e -> new StudentDTO(e.getScore(), e.getName()),
                Collectors.toList()),
            list -> { list.sort(Comparator.comparingInt(StudentDTO::getScore).reversed()); return list; }
        )
    ));

Примечание: написание кода для конкретной реализации делает его негибким. Возможно, вы захотите узнать, в чем преимущества использования абстракций. См. Что значит «запрограммировать на интерфейс»?

Попробуй это. (я добавил import static java.util.stream.Collectors.*;)

Map<Integer, List<StudentDTO>> map = list.stream()
    .collect(groupingBy(Student::getAge,
        mapping(e -> new StudentDTO(e.getScore(), e.getName()),
            collectingAndThen(toList(),
                x -> x.stream()
                    .sorted(Comparator.comparing(StudentDTO::getScore).reversed())
                    .collect(toList())))));

Другие вопросы по теме