如何根据 List<Object> 最佳实践计算总和 Object.getItem()?

How calculate summ Object.getItem() from List<Object> best practic?

我有模型列表

List<CallDetailFull> callDetails;//for example 50 items

是型号

public class CallDetailFull {
    private @Getter @Setter double dataUsage;
    private @Getter @Setter BigDecimal charge;
}

我需要得到 dataUsage 的总和和 charge

的总和

我能做到

BigDecimal totalCharge = BigDecimal.ZERO;
                    int totaldataUsage = 0;
                    for(CallDetailFull item: callDetails){
                        totalCharge.add(item.getCharge());
                        totaldataUsage += item.getDataUsage();
                    }

但我知道有一种方法可以通过 Collections.summ() 或类似的方法解决这个问题。

或者最好的解决方案是在模型本身中添加计算方法?

或者 lambda.....

这将是最佳实践以及如何去做?

首先,BigDecimal 是一个不可变的 class 并且它是 add 方法 returns 您 不能 [=25] 的新值=] 下降。此外,在 int 变量上使用 += 隐藏了这样一个事实,即由于将 double 值转换为 int:

而导致精度损失
BigDecimal totalCharge = BigDecimal.ZERO;
double totaldataUsage = 0;
for(CallDetailFull item: callDetails){
    totalCharge = totalCharge.add(item.getCharge());
    totaldataUsage += item.getDataUsage();
}

解决这个问题后,你的循环是一个很好的解决方案,其他解决方案不会改进它,尤其是当你只谈论 50 个元素时。

如果你真的想要一个流解决方案,你可以使用:

double totaldataUsage=callDetails.stream().mapToDouble(CallDetailFull::getDataUsage).sum();
BigDecimal totalCharge = callDetails.stream().map(CallDetailFull::getCharge)
   .reduce(BigDecimal::add).orElse(BigDecimal.ZERO);

这里有 2 种在 Java 8 中使用 Streams 求和的方法:

Double sumDouble = callDetails
                   .stream()
                   .collect(Collectors.summingDouble(CallDetailFull::getDataUsage));

BigDecimal sumBigDecimal = callDetails
                          .stream()
                          .map(CallDetailFull::getCharge)
                          .reduce(BigDecimal.ZERO, BigDecimal::add);

如果你使用你可以使用 java 8 个流和聚合,其性能非常好:

list.parallelStream().mapToDouble(CallDetailFull::getDataUsage).sum();
list.stream().map(CallDetailFull::getCharge).reduce(BigDecimal.ZERO, BigDecimal::add)