How to group objects from a list which can belong to two or more groups?

You can use groupByEach from Eclipse Collections.

Multimap<String, Item> itemsByCategory =
        ListIterate.groupByEach(myItemList, Item::getBelongsToCategories);

System.out.println(itemsByCategory);

Output:

{D=[Item{id=4}, Item{id=5}], 
E=[Item{id=5}], 
F=[Item{id=6}], 
A=[Item{id=1}, Item{id=2}, Item{id=6}], 
B=[Item{id=1}, Item{id=3}], 
C=[Item{id=2}, Item{id=3}]}

You can also use the Collectors2 utility class and groupByEach Collector with a Java Stream.

Multimap<String, Item> itemsByCategory = myItemList.stream().collect(
        Collectors2.groupByEach(
                Item::getBelongsToCategories,
                Multimaps.mutable.list::empty));

Note: I am a committer for Eclipse Collections.


You can use flatMap to map to SimpleEntry and then groupingBy as :

return items.stream()
        .flatMap(p -> p.getBelongsToCategories()
                .stream()
                .map(l -> new AbstractMap.SimpleEntry<>(l, p)))
        .collect(Collectors.groupingBy(Map.Entry::getKey,
                Collectors.mapping(Map.Entry::getValue,
                        Collectors.toList())));