我正在尝试使用Java 8 Stream API mapToDouble 方法,如下所示:
BigDecimal totalCost = order.getOrderlineList().stream()
.mapToDouble(Orderline::getPrice)
.sum();
问题是Orderline::getPrice
返回BigDecimal
,而不是Double
。因此,以上尝试无法编译(方法参考中的错误返回类型:无法将java.math.BigDecimal转换为doubele )。
看到Orderline#price
是BigDecimal
,如何使用Stream API(以及mapToDouble
或类似的东西)来获取我的totalCost
?
答案 0 :(得分:5)
您应该使用BigDecimal.add()
添加BigDecimal
,而不是将它们转换为double并再次返回,以避免舍入错误。要汇总所有价格,您可以使用Stream.reduce()
:
BigDecimal bigDecimal = order.getOrderLines().stream()
.map(OrderLine::getPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add);
摘自Stream.reduce()
的文档:
使用提供的标识值和关联累加函数对此流的元素进行缩减,并返回缩减后的值。这等效于:
T result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;
BigDecimal::add
是(a, b) -> a.add(b)
的缩写,它只返回a + b
。另外,标识元素为0
或BigDecimal.ZERO
。
答案 1 :(得分:2)
将Eclipse Collections与Java Streams结合使用,将会起作用:
BigDecimal totalCost = order.getOrderlineList().stream()
.collect(Collectors2.summingBigDecimal(Orderline::getPrice));
您还可以使用Iterate
类来稍微简化代码。
BigDecimal totalCost = Iterate.sumOfBigDecimal(order.getOrderlineList(), Orderline::getPrice)
注意:我是Eclipse Collections的提交者