首页 > 解决方案 > 当每个对象可以分成多个组时,如何对对象进行分组?

问题描述

我有一个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()));

它没有给出正确的答案。

标签: javajava-8java-streamgrouping

解决方案


You basically need a Stream that is made out of a Pair (I choose AbstractMap.SimpleEntry here) that has the left part as a Hobby and right as the Student (could be the other way around, does not matter).

Later just group those based on Hobby (that is a String in your case).

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 being a method reference that gets the key, you could write it as a lambda expression too, if it makes more sense for you:

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

推荐阅读