Reputation: 15472
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
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:
(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
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
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