Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 631
Elad Benda2 Avatar asked Nov 28 '22 20:11

Elad Benda2


2 Answers

Since Java 8 Map contains merge method which requires

  • key,
  • new value,
  • and function which will be used to decide what value to put in map if it already contains our key (decision will be made based on old and new value).

So you could simply use:

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

Now your map1 will contain all values from map2 and in case of same keys old value will be added to new value and result will be stored in map.

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}
like image 197
Pshemo Avatar answered Dec 10 '22 14:12

Pshemo


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);
    }
}
like image 35
zapl Avatar answered Dec 10 '22 13:12

zapl