Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Summing a map of doubles into an aggregated BigDecimal with Java Streams [duplicate]

I'm trying to use the Java 8 Stream API mapToDouble method like so:

BigDecimal totalCost = order.getOrderlineList().stream()
    .mapToDouble(Orderline::getPrice)
    .sum();

The problem is that Orderline::getPrice returns a BigDecimal, not a Double. Hence the attempt above fails to compile (Bad return type in method reference: cannot convert java.math.BigDecimal to doubele).

Seeing that Orderline#price is a BigDecimal, how can I use the Stream API (and either mapToDouble or something similar) to get my totalCost?

like image 255
hotmeatballsoup Avatar asked Dec 29 '25 14:12

hotmeatballsoup


1 Answers

You should add BigDecimals using BigDecimal.add() instead of converting them to double and back again to avoid rounding errors. To sum all prices you can use Stream.reduce():

BigDecimal bigDecimal = order.getOrderLines().stream()
        .map(OrderLine::getPrice)
        .reduce(BigDecimal.ZERO, BigDecimal::add);

From the docs of Stream.reduce():

Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. This is equivalent to:

T result = identity;
for (T element : this stream)
    result = accumulator.apply(result, element)
return result;

BigDecimal::add is a short form of (a, b) -> a.add(b), which simply returns a + b. For addition the identity element is 0 or BigDecimal.ZERO.

like image 144
Samuel Philipp Avatar answered Jan 01 '26 02:01

Samuel Philipp



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!