Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum multiple BigDecimals to a Map<String, BigDecimal>

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)

like image 526
baao Avatar asked Dec 01 '25 11:12

baao


2 Answers

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.

like image 85
Andreas Avatar answered Dec 03 '25 02:12

Andreas


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);
like image 45
Hazel Troost Avatar answered Dec 03 '25 02:12

Hazel Troost



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!