2016-07-21 12 views
-3

Sagen wir, ich habe mehrere N Karten mit-> Schlüssel: string val: ObjectWie mehrere Karten und Aggregatwerte Ergebnisse fusionieren Java mit Java8 bevorzugt

Ich möchte sie alle in eine große Karte verschmelzen, und die Summe ihrer Objekt abgelegt Werte:

zum Beispiel:

import java.util.HashMap; 
import java.util.Map; 

/** 
* Created by vitaly on 21/07/2016. 
*/ 
public class Merge { 

    static Map<String, Container> map1 = new HashMap<>(); 
    static Map<String, Container> map2 = new HashMap<>(); 
    static Map<String, Container> map3 = new HashMap<>(); 


    public void initMaps() { 
     map1.put("aaa", new Container(1, "title_aaa")); 
     map1.put("bbb", new Container(4, "title_bbb")); 

     map2.put("ccc", new Container(7, "title_ccc")); 
     map2.put("aaa", new Container(10, "title_aaa")); 

     map3.put("aaa", new Container(13, "title_aaa")); 
     map3.put("bbb", new Container(16, "title_bbb")); 
     ... 
     mapN.put(... 
    } 

    class Container { 
     public Container(int val1, String title) { 
      this.val1 = val1; 
      this.title = title; 

     } 

     int val1; 
     String title; 

    } 

    public static void main(String[] args) { 
     Merge.mergeMaps(map1, map2, map3); 
    } 

    public static Map<String, Container> mergeMaps(Map... maps) { 
     /** 
     * HOW create one merged map that sums the values 
     */ 
// The result should be: 
     //map(aaa, {24,title_aaa) //1+10+13 
     //map(bbb, {20,title_ccc) //4+16 
     //map(ccc, {7,title_ccc) //7 
     return map; 
    } 
} 

Bevorzugen Java 8, aber es egal :) nicht

vielen Dank!

+0

Will [ 'putAll' ] (http://stackoverflow.com/a/4299742/4009370) arbeiten? –

+0

glaube nicht, es wird die Werte der Klasse "Container" summieren – VitalyT

+2

Was ist Ihre Frage? Sie scheinen keine 'MergeMaps'-Methode zu haben. Fragen Sie nach einer Lösung, um all das zu tun, was Sie erreichen möchten, denn dann scheint es nicht so, als hätten Sie selbst genug getan. – ragingasiancoder

Antwort

2

Streamen Sie über die verschiedenen Karten, platform sie in eine. Verwenden Sie dann Collectors#groupingBy, um sie über ihre verschiedenen Werte (aaa, bbb usw.) zu sortieren. Dann streamen Sie das Ergebnis erneut, um neue Container Objekte mit den summierten Werten zu erstellen.

Verwenden Sie schließlich Collectors.toMap, um die benötigte Karte zu erstellen.

Wenn Sie Fragen haben, zögern Sie nicht.

public static Map<String, Container> mergeMaps(Map<String, Container>... maps) { 
    Map<String, Container> map = 
    Arrays.stream(maps) 
      .flatMap(x -> x.values().stream()) 
      .collect(Collectors.groupingBy(v -> v.getTitle().substring(6))) 
      .entrySet().stream() 
      .map(e -> new Merge().new Container(e.getValue().stream().mapToInt(x -> x.getVal()).sum(), e.getValue().get(0).getTitle())) 
      .collect(Collectors.toMap(e -> ((Container) e).getTitle().substring(6), e -> e)); 

    return map; 
} 

Und hier ist der Ausgang

{aaa=24 : title_aaa, ccc=7 : title_ccc, bbb=20 : title_bbb} 
0

Verwenden Map.merge

private Map<String,Container> mergeContainers(Map<String,Container> a, Map<String,Container> b) { 
    Map<String,Container> result = new HashMap<String,Container>(a); 

    for (Entry<String,Container> entry : b.entrySet()) { 
    result.merge(entry.getKey(), entry.getValue(), (aContainer,bContainer) -> MERGE_BOTH_CONTAINERS_HERE); 
    } 
    return result; 
} 

private Map<String,Container> mergeContainers(Iterable<Map<String,Container>> maps) { 
    return mergeContainers(maps, new HashMap<String,Container>()); 
} 

private Map<String,Container> mergeContainers(Iterable<Map<String,Container>> maps, Map<String,Container> merged) { 
    return maps.hasNext() 
     ? mergeContainers(maps, mergeContainers(merged, maps.next())) 
     : merged; 
    } 
} 

Jetzt in Ihrem Code Sie Ihre Karten mit zusammenführen können:

mergeContainers(Arrays.asList(map1, map2, map3)); 
+0

Wenn ich N Karten verwenden muss ... N-mal aufrufen "merge" -Funktion? ... Muss generischer sein .. – VitalyT