Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collect a Stream of Map<K,V> to Map<K,List<V>>

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

i.e.

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

a.flatMap(map -> map.entrySet().stream()).collect(
    Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (val1, val2) -> ??
);
like image 320
veruyi Avatar asked Jan 11 '17 23:01

veruyi


People also ask

How to collect a stream of list into map in Java?

Learn various ways of Collecting a Stream of List into Map using Java Streams API. Using Collectors.toMap and Collectors.groupingBy with example. Let’s consider, you have a User class and a List of the users which you want to convert to Map.

How to convert a stream to a map using collectors?

The Collectors.toMap () method takes two parameters as the input: KeyMapper: This function is used for extracting keys of the Map from stream value. ValueMapper: This function used for extracting the values of the map for the given key. The following are the examples of the toMap function to convert the given stream into a map:

How to map stream elements with duplicate map keys?

If the stream elements have elements where map keys are duplicate the we can use Collectors.groupingBy () to collect elements to map in Map<keyObj, List<Element>> format. Here for each map key, we will store all elements in a list as map value.

What is the difference between map () and collect () methods of stream?

The Stream.map () method is used to transform one object into another by applying a function. The collect () method of Stream class can be used to accumulate elements of any Stream into a Collection.


1 Answers

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

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())
   )
);
like image 186
NoDataFound Avatar answered Oct 23 '22 14:10

NoDataFound