我想采用以下方法:
public BigDecimal mean(List<BigDecimal> bigDecimals, RoundingMode roundingMode) {
BigDecimal sum = BigDecimal.ZERO;
int count=0;
for(BigDecimal bigDecimal : bigDecimals) {
if(null != bigDecimal) {
sum = sum.add(bigDecimal);
count++;
}
}
return sum.divide(new BigDecimal(count), roundingMode);
}
并使用Streams API对其进行更新。到目前为止,这是我得到的:
public BigDecimal average(List<BigDecimal> bigDecimals, RoundingMode roundingMode) {
BigDecimal sum = bigDecimals.stream()
.map(Objects::requireNonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
long count = bigDecimals.stream().filter(Objects::nonNull).count();
return sum.divide(new BigDecimal(count), roundingMode);
}
有没有办法避免两次流式传输(第二次获得计数)吗?
最佳答案
BigDecimal[] totalWithCount
= bigDecimals.stream()
.filter(bd -> bd != null)
.map(bd -> new BigDecimal[]{bd, BigDecimal.ONE})
.reduce((a, b) -> new BigDecimal[]{a[0].add(b[0]), a[1].add(BigDecimal.ONE)})
.get();
BigDecimal mean = totalWithCount[0].divide(totalWithCount[1], roundingMode);
对于那些认为有帮助的代码的可选文本描述(如果发现代码足以说明问题,请忽略。):
a
的(a,b)
值在第一个元素中具有部分和,在第二个元素中具有部分计数。 b
元素的第一个元素包含要添加到总和的每个BigDecimal值。不使用b
的第二个元素。