Java stream and groupping: put object to multiple groups

371 views Asked by At

I don't think, that it's called "groupping" but I need to achive the following: I have class

class Person {
   String name;
   Set<String> groups;
}

I have some persons:

  1. Father => {"Worker", "Men"}
  2. Mother => {"Woman"}
  3. Son => {"Student","Men"}
  4. Daughter => {"Student","Woman"}

So, every person can be part of multiple categories. And I want to get the following mapping:

"Worker" => {Father}
"Men" => {Father, Son}
"Student" => {Son, Daughter}
"Woman" => {Mother, Daughter}

Now I can do this with manual iterating over every person and putting them to Map<String,List<Person>>

I'm trying to find a more elegant wat to do it with streams (or StreamEx) oneliner, like:

List<Persons> family= ...;
Map<String,List<Person>> groupped = family.stream().groupByMultipleAttributes(Person::getGroups)
1

There are 1 answers

1
Eran On BEST ANSWER

You can generate all the associated pairs of groups and Persons, and then collect them with groupingBy into a Map:

Map<String,List<Person>> groups =
    family.stream()
          .flatMap(p -> p.getGroups()
                         .stream()
                         .map(g -> new SimpleEntry<>(g,p)))
          .collect(Collectors.groupingBy(Map.Entry::getKey,
                                         Collectors.mapping(Map.Entry::getValue,
                                                            Collectors.toList())));