I have a collection of invoices :
class Invoice {
int month;
BigDecimal amount
}
I'd like to merge these invoices, so I get one invoice per month, and the amount is the sum of the invoices amount for this month.
For example:
invoice 1 : {month:1,amount:1000}
invoice 2 : {month:1,amount:300}
invoice 3 : {month:2,amount:2000}
Output:
invoice 1 : {month:1,amount:1300}
invoice 2 : {month:2,amount:2000}
How can I do this with java 8 streams?
EDIT : as my Invoice class was mutable and it was not a problem to modify them, I choosed Eugene's solution
Collection invoices = list.collect(Collectors.toMap(Invoice::getMonth, Function.identity(), (left, right) -> {
left.setAmount(left.getAmount().add(right.getAmount()));
return left;
})).values();
解决方案
If you are OK returning a Collection it would look like this:
Collection invoices = list.collect(Collectors.toMap(Invoice::getMonth, Function.identity(), (left, right) -> {
left.setAmount(left.getAmount().add(right.getAmount()));
return left;
})).values();
If you really need a List:
list.stream().collect(Collectors.collectingAndThen(Collectors.toMap(Invoice::getMonth, Function.identity(), (left, right) -> {
left.setAmount(left.getAmount().add(right.getAmount()));
return left;
}), m -> new ArrayList<>(m.values())));
Both obviously assume that Invoice is mutable...