How to map a list using sublist as key and parent object as value

Viewed 278
public class User {
    private String userId;
    private String role;
    private List<String> privileges;
}

Given a List<User> users how do I get a Map<String, List<User>> where the key is each privilege from the user?

This code generates a Map<List, List> instead of the intended single string key

users.stream().collect(Collectors
.groupingBy(User::getPrivileges, HashMap::new, Collectors.mapping(v -> v, Collectors.toList())));

And if I do a flatmap, there's no way to reference the parent object

users.stream()
.flatMap(User::getPrivileges)
.collect(Collectors
.groupingBy(v->v, HashMap::new, Collectors.mapping(???, Collectors.toList())));
1 Answers

You need to create a temporary pair that holds both the privilege (after flattening the list) and the related user, which you can then use in a grouping collector:

Map<String, List<User>> result = users.stream()
        .flatMap(user -> user.getPrivileges()
                .stream()
                .map(priv -> new SimpleEntry<>(priv, user)))
        .collect(
                Collectors.groupingBy(Entry::getKey, 
                    Collectors.mapping(Entry::getValue, Collectors.toList())));
Related