I have a List<Student>
where each Student
may have multiple hobbies:
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"))
);
}
}
How to group the students based on hobbies? I tried this below code:
List<Student> data = StudentData.getData();
data.stream().collect(Collectors.groupingBy(s -> s.getHobbies().stream()));
It is not giving the right answer.
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())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With