Reputation: 20356
How can I sum the values in two maps and return the map with summed values using guava ? It can be safely assumed, both maps will have the same set of keys.
For e.g.:
Map<OccupancyType, BigDecimal> filteredPrice
[ 1 : 100 ]
[ 2 : 50 ]
[ 3 : 200 ]
Other map
Map<OccupancyType, BigDecimal> pkgPrice
[ 1 : 10 ]
[ 2 : 20 ]
[ 3 : 30 ]
Summed map
Map<OccupancyType, BigDecimal> sumPrice
[ 1 : 110 ]
[ 2 : 70 ]
[ 3 : 230 ]
I know I can iterate through these maps and sum the values easily, but is there a cleaner way to do this using one of the guava methods ?
Upvotes: 1
Views: 2355
Reputation: 92056
With functionaljava:
You could define a monoid instance for map. (I am surprised this is not already present in the library.)
public static <K, V> Monoid<Map<K, V>> mapMonoid(final Monoid<V> valueMonoid) {
return new Monoid<Map<K, V>>(
// associative binary operation
new F2<Map<K, V>, Map<K, V>, Map<K, V>>() {
public Map<K, V> f(Map<K, V> m1, Map<K, V> m2) {
// logic for merging two maps
}
},
// identity
new HashMap<K, V>()
);
}
And then use it so:
Map<Integer, Integer> mergedMap =
mapMonoid(Monoid.intAdditionMonoid).sum(m1, m2);
This way, you can even sum a list of maps.
List<Map<Integer, Integer>> maps = /* list of maps */;
Map<Integer, Integer> total =
mapMonoid(Monoid.intAdditionMonoid).sumLeft(maps);
Upvotes: 2
Reputation: 198113
Guava contributor here.
If you're sure that both maps have the same keys, I suppose you could do
Maps.transformEntries(pkgPrice,
new EntryTransformer<OccupancyType, BigDecimal, BigDecimal>() {
public BigDecimal transformEntry(OccupancyType key, BigDecimal pkPrice) {
return pkPrice.add(filteredPrice.get(key));
}
});
but that said, this seems to fall squarely into the category of "the direct approach is the cleanest." (Additionally, this implementation will recompute the values every time you request them, unless you do a copy. Still, this is almost certainly unnecessarily complicated; the direct, imperative approach is almost certainly preferable here.
Upvotes: 4