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
?
You should add BigDecimal
s 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
.