Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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"]}.

like image 299
Alex Kornakov Avatar asked Jun 08 '18 14:06

Alex Kornakov


1 Answers

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.

like image 57
Ousmane D. Avatar answered Nov 10 '22 10:11

Ousmane D.