Alex Kornakov
Alex Kornakov

Reputation: 313

How do I convert a List<Entry> to Map where value is a list using streams?

How do I convert a List<Entry> to Map<Entry::getKey, List<Entry::getValue>> using streams in Java 8?

I couldn't come up with a good KeySelector for Collectors.toMap():

List<Entry<Integer, String>> list = Arrays.asList(Entry.newEntry(1, "a"), Entry.newEntry(2, "b"), Entry.newEntry(1, "c"));
        Map<Integer, List<String>> map = list.stream().collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));

What I want to get: {'1': ["a", "c"], '2': ["b"]}.

Upvotes: 5

Views: 989

Answers (1)

Ousmane D.
Ousmane D.

Reputation: 56469

You can do so by using the groupingBy collector along with mapping as the downstream collector:

myList.stream()
       .collect(groupingBy(e -> e.getKey(), mapping(e -> e.getValue(), toList())));

import required:

import static java.util.stream.Collectors.*;

You can actually accomplish the same result with the toMap collector:

 myList.stream()
       .collect(toMap(e -> e.getKey(), 
                 v -> new ArrayList<>(Collections.singletonList(v.getValue())),
              (left, right) -> {left.addAll(right); return left;}));

but it's not ideal when you can use the groupingBy collector and it's less readable IMO.

Upvotes: 10

Related Questions