2015-03-04 5 views
13

Ich versuche, mehr als ein Hashmaps zu verschmelzen auch die Werte der gleichen Tonart Summe, Ich möchte mein Problem mit Spielzeug Beispiel erklären, wiewie mehr als ein Hashmaps verschmelzen auch die Werte der gleichen Schlüssel in Java Summe

folgt
HashMap<String, Integer> m = new HashMap<>(); 
    HashMap<String, Integer> m2 = new HashMap<>(); 

    m.put("apple", 2); 
    m.put("pear", 3); 
    m2.put("apple", 9); 
    m2.put("banana", 6); 

ich versuchte putAll

m.putAll (m2);

Ausgabe lautet wie folgt {Banane = 6, Apfel = 9, Birne = 3}

aber das Ergebnis ist für dieses Problem nicht wahr. I ausgeben wollen als

{Banane = 6, Apfel = 11, Birne = 3}

wie kann dieses Ergebnis in Java du bekommen?

+0

ı überschreiben wollte Ergebnis hashmap deutlicher als {Banane = 6, Apfel = 9 + 2, Birne = 3} wenn mehr als eine hashmaps gleiche Schlüssel haben, Ergebnisse werden Summe von Werten. Wenn andere hashmaps nicht denselben Schlüssel haben, ändert sich der Wert nicht und alle Schlüssel in allen hashmaps sind im Ergebnis hashmaps mit ihren Werten –

Antwort

0

So etwas sollte funktionieren:

for (Map.Entry<String, Integer> entry : map.entrySet()) { 
    String map1_key = entry.getKey(); 
    int map1_value = entry.getValue(); 

    //check: 
    if(map2.get(map1_key)!=null){ 
    int map2_value = map2.get(map1_key); 
    //merge: 
    map3.put(map1_key,map1_value+map2_value); 
    }else{ 
    map3.put(map1_key,map1_value); 
    } 
} 


    for (Map.Entry<String, Integer> entry2 : map2.entrySet()) { 
     String map2_key = entry2.getKey(); 
     int map2_value = entry2.getValue(); 

     //check: 
     if(map1.get(map2_key)!=null){ 
     int map1_value = map1.get(map2_key); 
     //merge: 
     map3.put(map2_key,map1_value+map2_value); 
     }else{ 
     map3.put(map2_key,map2_value); 
     } 
    } 
+0

Was ist, wenn der Schlüssel von map1 in map2 keinen Wert hat? Und was ist mit Einträgen, die nur in map2 existieren? –

+0

danke, aber es ist nicht meine Problemlösung genau. Wenn alle Karten denselben Schlüssel haben, funktioniert es, aber wenn es einen anderen Schlüssel gibt, wird es keine Arbeit sein. –

+0

oh Entschuldigung, ich dachte du hast gesagt, du müsstest die WERTE basierend auf den gleichen Schlüsseln kombinieren – Petro

0

Wenn der Schlüssel vorhanden ist, fügen Sie es Wert ist. Wenn nicht, einfügen.

Hier ist ein einfaches Beispiel, das eine Karte in eine andere übergeht:

Foo oldVal = map.get(key); 
if oldVal == null 
{ 
    map2.put(key, newVal); 
} 
else 
{ 
    map2.put(key, newVal + oldVal); 
} 

Offensichtlich Sie eine Schleife haben über die erste Karte, so dass Sie alle seine Eingaben verarbeiten kann, aber das ist trivial.

+0

ich weiß aber ich kann es nicht schreiben jemand fragen ähnliche Fragen, aber in Scala nicht wissen, scala http://stackoverflow.com/questions/7076128/best-way-to-merge-two-maps-and-sum-the-values-of-same-key –

1

Diese Methode sollte es tun (in Java 5+)

public static <K> Map<K, Integer> mergeAndAdd(Map<K, Integer>... maps) { 
    Map<K, Integer> result = new HashMap<>(); 
    for (Map<K, Integer> map : maps) { 
     for (Map.Entry<K, Integer> entry : map.entrySet()) { 
      K key = entry.getKey(); 
      Integer current = result.get(key); 
      result.put(key, current == null ? entry.getValue() : entry.getValue() + current); 
     } 
    } 
    return result; 
} 
+0

es funktioniert. ı wie deine Antwort vielen Dank –

19

Wenn Sie Java 8 verwenden, können Sie die neue merge Methode der Karte verwenden können.

m2.forEach((k, v) -> m.merge(k, v, (v1, v2) -> v1 + v2)); 
+1

Was ist mit Einträgen in 'm', die nicht in' m2' vorkommen? – sprinter

+0

'm' enthält die zusammengeführten Ergebnisse, die von diesem Code ausgegeben werden:' {banana = 6, apple = 11, pear = 3} ' – prunge

+0

Ah, ich sehe - Sie verschmelzen in die ursprüngliche Karte, anstatt eine neue zu erstellen. Ich hatte nicht realisiert, dass das das OP beabsichtigte, aber ich sehe das jetzt in seiner Frage. Es beruht also im Wesentlichen auf der Veränderbarkeit der ursprünglichen Karte. – sprinter

4

Dies ist ein sehr netter Anwendungsfall für Java 8 Streams. Sie können die Ströme der Einträge concatentate und sie dann in einer neuen Karte sammeln:

Map<String, Integer> combinedMap = Stream.concat(m1.entrySet().stream(), m2.entrySet().stream()) 
    .collect(Collectors.groupingBy(Map.Entry::getKey, 
      Collectors.summingInt(Map.Entry::getValue))); 

Es gibt viele nette Dinge über diese Lösung, einschließlich der in der Lage zu machen, parallel, um so viele Karten erweitern, wie Sie wollen und in der Lage sein, die Karten bei Bedarf trivial zu filtern. Es erfordert auch nicht, dass die Originalkarten änderbar sind.

1

Hier ist meine schnelle und schmutzige Umsetzung:

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

public class MapMerger { 

    public static void main(String[] args) { 
     HashMap<String, Integer> m = new HashMap<>(); 
     HashMap<String, Integer> m2 = new HashMap<>(); 

     m.put("apple", 2); 
     m.put("pear", 3); 
     m2.put("apple", 9); 
     m2.put("banana", 6); 

     final Map<String, Integer> result = (new MapMerger()).mergeSumOfMaps(m, m2); 
     System.out.println(result); 
    } 

    public Map<String, Integer> mergeSumOfMaps(Map<String, Integer>... maps) { 
     final Map<String, Integer> resultMap = new HashMap<>(); 
     for (final Map<String, Integer> map : maps) { 
      for (final String key : map.keySet()) { 
       final int value; 
       if (resultMap.containsKey(key)) { 
        final int existingValue = resultMap.get(key); 
        value = map.get(key) + existingValue; 
       } 
       else { 
        value = map.get(key); 
       } 
       resultMap.put(key, value); 
      } 
     } 
     return resultMap; 
    } 
} 

Ausgang:

{banana=6, apple=11, pear=3} 

Es gibt einige Dinge, die Sie (wie null Prüfung) tun sollte, und ich bin nicht sicher, ob es das schnellste ist . Dies ist auch spezifisch für Ganzzahlen. Ich versuchte, einen Generics der Number Klasse zu machen, aber Sie würden diese Methode für jeden Typ benötigen (Byte, int, kurz, länger, usw.)

+0

es kann nicht die schnellste sein, aber es ist klarer und verständlicher für mich. Vielen Dank –

+0

und mit viel Respekt Danke – Goodlife

1

ı verbessern Lucas Ross Code.Karte nach der anderen durch Eingabe von anstatt in Funktion gebe ich alle Karten ein Mal mit Arraylist von hashmap zu funktionieren, wie die

public HashMap<String, Integer> mergeAndAdd(ArrayList<HashMap<String, Integer>> maplist) { 
    HashMap<String, Integer> result = new HashMap<>(); 
    for (HashMap<String, Integer> map : maplist) { 
     for (Map.Entry<String, Integer> entry : map.entrySet()) { 
      String key = entry.getKey(); 
      Integer current = result.get(key); 
      result.put(key, current == null ? entry.getValue() : entry.getValue() + current); 
     } 
    } 
    return result; 
} 

}

es auch funktioniert. dank Everybody

Verwandte Themen