Elad Benda2
Elad Benda2

Reputation: 15472

how to easily sum two hashMap<String,Integer>?

I have two HashMap<String,Integer>

How can I sum them easily?

Meaning that for String "a" the key will be sum of (value from Map1 + value from Map2)?

I can iterate every item of Map2 and add manually to Map1.

But thought there might be an easier way?

I prefer summing the Integers into one of the maps. Not creating a new one

Upvotes: 7

Views: 12586

Answers (3)

Pshemo
Pshemo

Reputation: 124225

I prefer summing the Integers into one of the maps. Not creating a new one

In that case you can use merge method added to Map interface in Java 8. Otherwise take a look at other answers like https://stackoverflow.com/a/33640413

Anyway Map#merge(key, value, merginFunction) method is similar to Map#add(key, value). Only difference is fact that it requires third argument which is:

  • function used to decide what value to put in map if it already contains specified key. Decision will be made based on old and new value (so its lambda may look like (v1, v2) -> v1 + v2 for summing values, or we could use Integer::sum method reference).

So you could simply use:

map2.forEach((k, v) -> map1.merge(k, v, Integer::sum));

Now your map1 will copy all key-values from map2 and in case it already has such key, value will be calculated by adding old and new value. Result will be stored in map under that common key.

DEMO:

Map<String, Integer> m1 = new HashMap<>();
m1.put("a", 1);
m1.put("b", 2);
Map<String, Integer> m2 = new HashMap<>();
m2.put("a", 3);
m2.put("c", 10);

System.out.println(m1);
System.out.println(m2);

//iterate over second map and merge its elements into map 1 using 
//same key and sum of values
m2.forEach((k, v) -> m1.merge(k, v, Integer::sum));

System.out.println("===========");
System.out.println(m1);

Output:

{a=1, b=2}
{a=3, c=10}
===========
{a=4, b=2, c=10}

Upvotes: 22

zapl
zapl

Reputation: 63955

in case you like Java 8:

Map<String, Integer> sum(Map<String, Integer>... maps) {
    return Stream.of(maps)    // Stream<Map<..>>
            .map(Map::entrySet)  // Stream<Set<Map.Entry<..>>
            .flatMap(Collection::stream) // Stream<Map.Entry<..>>
            .collect(Collectors.toMap(Map.Entry::getKey,
                                      Map.Entry::getValue,
                                      Integer::sum));
}

can sum up arbitrary amounts of maps. It turns the array of maps into a Stream<Map.Entry<String, Integer> in the first few lines, then collects all the entries into a new Map while supplying a "merge function" in case of duplicate values.

alternatively something along the lines of

void addToA(HashMap<String, Integer> a, HashMap<String, Integer> b) {
    for (Entry<String, Integer> entry : b.entrySet()) {
        Integer old = a.get(entry.getKey());
        Integer val = entry.getValue();
        a.put(entry.getKey(), old != null ? old + val : val);
    }
}

Upvotes: 7

user5500105
user5500105

Reputation: 297

Unfortunately, there is no easy way. You need to iterate them manually.

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class HashMapSum {

    public static void main(String[] args) {
        Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("a", 1);
        map1.put("b", 2);
        map1.put("c", 3);

        Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("a", 4);
        map2.put("b", 5);
        map2.put("d", 6);

        Set<String> keySet = new HashSet<String>();
        keySet.addAll(map1.keySet());
        keySet.addAll(map2.keySet());

        Map<String, Integer> map3 = new HashMap<String, Integer>();
        Integer val1, val2;
        for (String key : keySet) {
            val1 = map1.get(key);
            val1 = (val1 == null ? 0 : val1);
            val2 = map2.get(key);
            val2 = (val2 == null ? 0 : val2);
            map3.put(key, val1 + val2);
        }

        System.out.println(map3.toString());
    }
}

Upvotes: 1

Related Questions