7

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

5
  • Do you want to create new map which will be combination of previous two, or do you want to update first map by adding to it second map? Commented Nov 10, 2015 at 21:40
  • I feel like an example of the expected result structure would be useful Commented Nov 10, 2015 at 21:40
  • 5
    Show us some code. Intuitively, I would say: get both keySets, join them in one Set, look up each value in each map, sum them up and add them to a new map. Commented Nov 10, 2015 at 21:42
  • @Pshemo I prefer summing the Integers into one of the maps. Not creating a new one Commented Nov 10, 2015 at 21:51
  • Do you have to construct a new HashMap per se? You can create an object that has references to both HashMaps and acts as a hashmap by query both. A bit like a view on a collection. Commented Nov 10, 2015 at 21:56

3 Answers 3

22

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}
Sign up to request clarification or add additional context in comments.

Comments

7

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

Comments

1

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());
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.