【发布时间】:2014-07-04 15:21:40
【问题描述】:
我有以下课程:
class Money {
CurrencyUnit currencyUnit;
BigDecimal amount;
}
在我的应用程序中,我得到了一些 Money 对象的随机列表:
currencyUnit | amount
---------------------
EUR | 5.1
EUR | 0
USD | 1.09
EUR | 42
USD | 3
现在我想使用 Java 8 Stream API 创建以下结果(只需为每个 currencyUnit 的金额调用 BigDecimal::add):
currencyUnit | amount
---------------------
EUR | 47.1
USD | 4.09
我已经知道/做过的事情:
Stream<Money> moneyStream = moneyList.stream();
到这里就结束了。我知道我可以使用Collector 生成Map<CurrencyUnit, List<Money>>:
moneyStream.collect(Collectors.groupingBy(m -> m.getCurrencyUnit());
但是我还是要遍历所有的键值对并总结数量数据。
什么是正确的(并且可能是最简单的方法)这样做?不可能这么复杂吧? :)
编辑:如果不清楚我需要什么,这是我的旧 Java 代码:
Map<CurrencyUnit, Money> map = new HashMap<>();
moneyList.stream().forEach(e -> {
Money m = map.get(e.getCurrencyUnit());
if(m == null) {
m = new Money();
m.setAmount(BigDecimal.ZERO);
m.setCurrencyUnit(e.getCurrencyUnit());
map.put(e.getCurrencyUnit(), m);
}
m.setAmount(m.getAmount().add(e.getAmount()));
});
return map.values();
编辑 2:另一种不太优雅的解决方案:
List<Money> list = inputList.stream()
.collect(Collectors.groupingBy(Money::getCurrencyUnit))
.values().stream().map(ml -> {
Money money = new Money();
ml.forEach(m -> {
if(money.getCurrencyUnit() == null) {
money.setCurrencyUnit(m.getCurrencyUnit());
money.setAmount(m.getAmount());
} else {
money.setAmount(money.getAmount().add(m.getAmount()));
}
});
return money;
}).collect(Collectors.toList());
【问题讨论】:
标签: java java-8 java-stream