Я использую 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)]}




Чтобы отсортировать каждый список 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())))));