Collect the flow of the map <K, V> onto the map <K, List <V>>

I have Stream< Map< K, V > > , and I'm trying to combine these maps together, but keep duplicate values ​​in a list, so the final type will be Map< K, List<V> > . Is there any way to do this? I know that the toMap collector has a binary function to basically choose which value is returned, but can it track the converted list?

i.e.

if a is Stream< Map< String, Int > >

 a.flatMap(map -> map.entrySet().stream()).collect( Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (val1, val2) -> ?? ); 
+5
source share
2 answers

Use groupingBy : see javadoc, but in your case it should be something like this:

 a.flatMap(map -> map.entrySet().stream()) .collect( Collectors.groupingBy( Map.Entry::getKey, HashMap::new, Collectors.mapping(Map.Entry::getValue, toList()) ) ); 

Or:

 a.map(Map::entrySet).flatMap(Set::stream) .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, toList()) ) ); 
+8
source

This is a bit more verbose than a groupingBy solution, but I just wanted to point out that you can also use toMap (as you originally planned), providing a merge function:

  a.flatMap(map -> map.entrySet().stream()).collect( Collectors.toMap(Map.Entry::getKey, entry -> { List<Integer> list = new ArrayList<>(); list.add(entry.getValue()); return list; }, (list1, list2) -> { list1.addAll(list2); return list1; })); 
0
source

Source: https://habr.com/ru/post/1262663/


All Articles