我有下面的類:總結列表<X>列出<X>與Java 8個流API
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創建以下結果(僅針對每個貨幣單位的金額調用BigDecimal::add
):
currencyUnit | amount
---------------------
EUR | 47.1
USD | 4.09
我已經知道/ DID:
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());
謝謝。這與我所需要的很接近,但是你的代碼給了我一個'Map'。是不是有可能找回一個'List'或者'Set'? (沒有手動創建新的Money對象等) –
就在5分鐘前,迭代entrySet的想法出現在我的腦海中,但我想:這真的很醜,必須有更性感/優雅的東西。 '---'但我認爲你給出的答案是這樣做的唯一方法。 ' - '現在我想:'moneyStream.collect(Collectors.groupingBy(m - > m.getCurrencyUnit());'然後用map生成'Map>'。 values()。stream()'產生一個'List '?! –