2017-01-11 5 views
5

ich ein Stream< Map< K, V > > haben und ich versuche, diese Karten zusammen zu fusionieren, sondern erhält doppelte Werte in einer Liste, so wäre die letzte Art Map< K, List<V> > sein. Gibt es eine Möglichkeit, dies zu tun? Ich weiß, dass der Kollektor toMap eine binäre Funktion hat, um im Grunde zu wählen, welcher Wert zurückgegeben wird, aber kann er die konvertierte Liste verfolgen?einen Strom von Karte <K,V> auf Karte <K,List<V>>

dh

wenn a ist eine Stream< Map< String, Int > >

a.flatMap(map -> map.entrySet().stream()).collect(
    Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (val1, val2) -> ?? 
); 

Antwort

8

Verwendung groupingBy: siehe javadoc, aber in Ihrem Fall sollte es so etwas wie das sein:

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

Oder:

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

können Sie Verwende ['groupingBy (Function, Collector)'] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function- java.util.stream.Collector-) und lassen Sie 'HashMap :: new' weg. Für diejenigen, die Methodenreferenzen bevorzugen, können Sie auch 'a.map (Map :: entrySet) .flatMap (Set :: stream)' verwenden. – shmosel

+0

Danke Ich habe meine Antwort bearbeitet. – NoDataFound

0

Das ist ein bisschen wortreicher als die groupingBy Lösung, aber ich wollte nur darauf hinweisen, dass es auch möglich ist toMap zu verwenden (wie Sie zunächst vorgenommen haben), indem die Merge-Funktion bereitstellt:

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; 
       })); 
Verwandte Themen