Java 8 Stream API: how to use GroupingBy to have the same object in multiple groups?

1Z10 :

I have the following class:

public class A{
    public List<String> groups;
}

and I'm trying to build a Map<String, List<A>> where the key represents the group.

I know how to do when class A belongs to a single group:

List<A> aList = getAList();
Map<String, List<A>> aByGroupMap = aList.stream().parallel()
           .collect(Collectors.groupingBy(a -> a.getGroup()));

But how can I adapt the above code in such a way that an object A is mapped to multiple groups? E.g. what if object a1 belongs to the groups ["G", "H", "I"] and object a2 belongs to the groups ["H", "I"] ?

Eritrean :

You could try something like this:

Map<String, List<A>> aByGroupMap = aList.stream()
    .flatMap(a -> a.getGroups().stream()
            .map(g -> new AbstractMap.SimpleEntry<>(g , a)))
    .collect(Collectors.groupingBy(Map.Entry::getKey,
            Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

Or if you have a small previously known set of your groups something like

Set<String> myGroups = Set.of("A","B","C");

you could do something like:

Map<String,List<A>> map = new HashMap<>();
    myGroups.forEach(g -> {
        aList.stream().filter(a -> a.getGroups().contains(g)).forEach(a ->{
            map.computeIfAbsent(g, s -> new ArrayList<>()).add(a);
        });
    });

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324202&siteId=1