Victor Grazi Victor Grazi -3 years ago 106
Java Question

How can I use groupingBy to return a List<String, String>

I have a List of

GroupUser
instances with
String getGroup()
and
String getName()
methods.
I want to return a
Map<String, List<String>>
where the key is the group and the value is the list of names for that group.

If I use

Map<String, List<GroupUser>> groupUserList = users.stream()
.collect(Collectors.groupingBy(GroupUser::getGroup));


that returns
Map<String, List<GroupUser>>


How can I get a
Map<String, List<String>>
directly

Answer Source

You can get a Map<String, List<String>> where the key is the group and the value is a list of names with:

    Map<String, List<String>> groupUserList = users.stream()
            .collect(
                    Collectors.groupingBy(GroupUser::getGroup, 
                            Collectors.mapping(GroupUser::getName, 
                                    Collectors.toList())));

Edit

Explaination:

Looking at groupingBy javadocs we see that 1 of the overloads has the signature:

public static <T,K,A,D> Collector<T,?,Map<K,D>> groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)

You can think of this downstream as a collector that tells the stream what to do with the elements that it separated by key (in our case the group is the key).

Notice that it is another collector. Next we want to transform a GroupUser into a String which is it's name. We know we transform elements of a stream with map. However this takes a Collector.

Look further into the Collectors API we see that we already have a collector that maps elements and takes another Collector

public static <T,U,A,R> Collector<T,?,R> mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)

Now from the docs: downstream - a collector which will accept mapped values. Since we mapped GroupedUser to it's name the last thing left to do is to collect them in a list and that is one of the most commonly used collectors. Collectors.toList()

Bottom line: Simple usage of collectors tells you that this is where you finished the processing of your stream, however we can compose collectors in more complex scenarios like this one.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download