brainydexter
brainydexter

Reputation: 20356

how can I sum the values in two maps and return the value using guava

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

Answers (2)

missingfaktor
missingfaktor

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

Louis Wasserman
Louis Wasserman

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

Related Questions