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())