I'm trying to sum multiple BigDecimals from a List. Currently, I'm using two streams, but would like to have only one stream if possible. I'm unsure how I can rewrite below in a performant way.
BigDecimal totalCharges = tableRowDataList.stream()
.map(el -> el.getSums().getCharges())
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalFees = tableRowDataList.stream()
.map(el -> el.getSums().getFees())
.reduce(BigDecimal.ZERO, BigDecimal::add);
As you can see, the streams are doing basically the same, only the call to getCharges/getFees differ.
What is the best way to get a resulting Map<String, BigDecimal> from above? (Where key would be charges/fees)
First you create a class for collecting the result.
You then do the same as BigDecimal has, i.e. a ZERO constant and an add() method.
public class ChargesAndFees {
private static final ZERO = new ChargesAndFees(BigDecimal.ZERO, BigDecimal.ZERO);
private final BigDecimal charges;
private final BigDecimal fees;
// constructor and getters
public ChargesAndFees add(ChargesAndFees that) {
return new ChargesAndFees(this.charges.add(that.charges),
this.fees.add(that.fees));
}
}
Now you can do the stream logic
ChargesAndFees totals = tableRowDataList.stream()
.map(el -> new ChargesAndFees(el.getSums().getCharges(),
el.getSums().getFees()))
.reduce(ChargesAndFees.ZERO, ChargesAndFees::add);
If you insist, you can then convert the values in totals into a Map.
If you have a list of objects List<TableRowDataElement>, each of which has a Sums object-- do you control the definition of TableRowDataElement and/or Sums?
If you create an add method in either TableRowDataElement or Sums, then you can simplify this without the need for an additional class--
Sums sums = tableRowDataList.stream()
.map(el -> el.getSums())
.reduce(new Sums(0,0), Sums::add);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With