1

如何对两个地图中的值求和并使用 guava 返回具有求和值的地图?可以安全地假设,两个映射将具有相同的键集。

例如:

Map<OccupancyType, BigDecimal> filteredPrice
[ 1 : 100 ]
[ 2 : 50 ]
[ 3 : 200 ]

其他地图

Map<OccupancyType, BigDecimal> pkgPrice
[ 1 : 10 ]
[ 2 : 20 ]
[ 3 : 30 ]

求和图

Map<OccupancyType, BigDecimal> sumPrice
[ 1 : 110 ]
[ 2 : 70 ]
[ 3 : 230 ]

我知道我可以遍历这些映射并轻松地对这些值求和,但是有没有一种更简洁的方法可以使用其中一种番石榴方法来做到这一点?

4

2 回答 2

4

番石榴贡献者在这里。

如果您确定两个地图具有相同的键,我您可以这样做

Maps.transformEntries(pkgPrice,
    new EntryTransformer<OccupancyType, BigDecimal, BigDecimal>() {
  public BigDecimal transformEntry(OccupancyType key, BigDecimal pkPrice) {
    return pkPrice.add(filteredPrice.get(key));
  }
});

但话虽如此,这似乎完全属于“直接方法最干净”的范畴。 (此外,此实现将在您每次请求它们时重新计算值,除非您进行复制。不过,这几乎肯定是不必要的复杂;在这里,直接的、命令式的方法几乎肯定是更可取的。

于 2012-06-27T10:02:01.347 回答
2

使用功能性java

您可以为 map 定义一个monoid实例。(我很惊讶这还没有出现在图书馆里。)

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

然后使用它:

Map<Integer, Integer> mergedMap = 
  mapMonoid(Monoid.intAdditionMonoid).sum(m1, m2);

这样,您甚至可以汇总地图列表。

List<Map<Integer, Integer>> maps = /* list of maps */;
Map<Integer, Integer> total = 
  mapMonoid(Monoid.intAdditionMonoid).sumLeft(maps);
于 2012-06-27T10:46:08.320 回答