Victor Grazi
Victor Grazi

Reputation: 16510

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

I have a List of GroupUserinstances 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

Upvotes: 0

Views: 1308

Answers (1)

pedromss
pedromss

Reputation: 2453

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.

Upvotes: 5

Related Questions