当每个对象可以放在多个组中时,如何对对象进行分组?

2022-02-21 00:00:00 grouping java-8 java java-stream

我有一个List<Student>,其中每个Student可能有多个爱好:

public class StudentData {
    public static List<Student> getData() {
        return Arrays.asList(
            new Student(1, "a1", 1, Arrays.asList("cricket", "football", "basketball")),
            new Student(2, "a2", 1, Arrays.asList("chess", "football")),
            new Student(3, "a3", 2, Arrays.asList("running")),
            new Student(4, "a4", 2, Arrays.asList("throwball", "football")),
            new Student(5, "a5", 3, Arrays.asList("cricket", "basketball")),
            new Student(6, "a6", 4, Arrays.asList("cricket")), new Student(7, "a7", 5, Arrays.asList("basketball")),
            new Student(8, "a8", 6, Arrays.asList("football")),
            new Student(9, "a9", 8, Arrays.asList("tennis", "swimming")),
            new Student(10, "a10", 8, Arrays.asList("boxing", "running")),
            new Student(11, "a11", 9, Arrays.asList("cricket", "football")),
            new Student(12, "a12", 11, Arrays.asList("tennis", "shuttle")),
            new Student(13, "a13", 12, Arrays.asList("swimming"))
        );
    }
}

如何根据爱好对学生进行分组?我尝试了以下代码:

List<Student> data = StudentData.getData();
data.stream().collect(Collectors.groupingBy(s -> s.getHobbies().stream()));

它没有给出正确答案。


解决方案

您基本上需要一个由Pair(我在这里选择AbstractMap.SimpleEntry)组成的Stream,它的左边部分作为业余爱好,右边部分作为学生(可以反过来,不要紧)。

稍后只需根据Hobby(在您的案例中是字符串)对它们进行分组。

data.stream()
    .flatMap(student -> student.getHobbies().stream().map(hobby -> new SimpleEntry<>(hobby, student)))
    .collect(Collectors.groupingBy(
            Entry::getKey,
            Collectors.mapping(Entry::getValue, Collectors.toList())
));

Entry::getKey作为获取键的方法引用,如果对您更有意义,您也可以将其编写为lambda表达式:

Collectors.groupingBy(entry -> entry.getKey())

相关文章