汇总列表<;X>;列出<;X>;使用Java8流API
我有以下课程:汇总列表<;X>;列出<;X>;使用Java8流API,java,java-8,java-stream,Java,Java 8,Java Stream,我有以下课程: class Money { CurrencyUnit currencyUnit; BigDecimal amount; } 在我的应用程序中,我得到了一些随机的Money对象列表: currencyUnit | amount --------------------- EUR | 5.1 EUR | 0 USD | 1.09 EUR | 42 USD | 3 现在,我想使用Jav
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
):
我已经知道/做过的事情:
Stream<Money> moneyStream = moneyList.stream();
但是我仍然需要遍历所有的键值对,并总结出数据量
做这件事的正确方法(可能是最简单的方法)是什么?不会那么复杂吧<代码>:)
编辑:如果不清楚我需要什么,下面是我的旧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();
Map Map=newhashmap();
moneyList.stream().forEach(e->{
Money m=map.get(如getCurrencyUnit());
如果(m==null){
m=新货币();
m、 设置金额(BigDecimal.ZERO);
m、 setCurrencyUnit(如getCurrencyUnit());
put(e.getCurrencyUnit(),m);
}
m、 setAmount(m.getAmount().add(e.getAmount());
});
返回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());
List List=inputList.stream()
.collect(收集器.groupingBy(Money::getCurrencyUnit))
.values().stream().map(ml->{
钱=新钱;
ml.forEach(m->{
if(money.getCurrencyUnit()==null){
money.setCurrencyUnit(m.getCurrencyUnit());
money.setAmount(m.getAmount());
}否则{
money.setAmount(money.getAmount().add(m.getAmount());
}
});
退钱;
}).collect(Collectors.toList());
您可以使用groupingBy
收集器按CurrencyUnit
对对象进行分组。没有第二个参数,groupingBy
方法将元素收集到一个列表中。但是,如果需要其他内容,也可以指定下游收集器
对于int
和long
可以使用collector::summingit
和collector::summingLong
。对于BigDecimal
,您可以回到collector::reduce
:
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.reducing;
Map<CurrencyUnit, BigDecimal> result = moneyList.stream()
.collect(
groupingBy(
Money::getCurrencyUnit,
reducing(BigDecimal.ZERO, Money::getAmount, BigDecimal::add)));
导入静态java.util.stream.Collectors.groupingBy;
导入静态java.util.stream.Collectors.reduction;
映射结果=moneyList.stream()
.收集(
分组依据(
货币:getCurrencyUnit,
减少(BigDecimal.ZERO,Money::getAmount,BigDecimal::add));
编辑:您还可以创建
列表
:
List result=moneyList.stream()
.收集(
分组依据(
货币:getCurrencyUnit,
减少(BigDecimal.ZERO,Money::getAmount,BigDecimal::add)))
.entrySet().stream()
.map(e->newmoney(e.getKey(),e.getValue())
.collect(toList());
谢谢。这很接近我所需要的,但是你的代码给了我一张地图
。你不可能拿回列表
或集合
?(不需要手动创建新的货币
对象等)就在5分钟前,我想到了迭代入口集的想法,但我想:那真的很难看,一定有更性感/优雅的东西。--
但我认为你给出的答案是唯一的方法。--
刚才我想:moneyStream.collector(Collectors.groupingBy(m->m.getCurrencyUnit());
然后使用生成的Map
和Map.values().stream()
生成一个列表
?!
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());
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.reducing;
Map<CurrencyUnit, BigDecimal> result = moneyList.stream()
.collect(
groupingBy(
Money::getCurrencyUnit,
reducing(BigDecimal.ZERO, Money::getAmount, BigDecimal::add)));
List<Money> result = moneyList.stream()
.collect(
groupingBy(
Money::getCurrencyUnit,
reducing(BigDecimal.ZERO, Money::getAmount, BigDecimal::add)))
.entrySet().stream()
.map(e -> new Money(e.getKey(), e.getValue())
.collect(toList());