Java 8 lambda aggregate



我在lambdas上遇到了一个小问题。 如何遍历它并在每次迭代时向我的变量 currentLateAmountDouble 添加值?

BigDecimal currentLateAmountDouble = BigDecimal.ZERO;
Collection<VPO> lines = BO_Contract.getLines(trxName, contractVPO.getID(), RContractLine.LineNo + " ASC ", ctx);
if (lines != null && !lines.isEmpty()) {
    if (lines.stream()
             .filter(line -> onDate.compareTo(line.getDateValue(RContractLine.TermDate)) > 0) != null) {
        lines.forEach(line -> currentLateAmountDouble = currentLateAmountDouble.add(NumberUtils.getAmount(line.getDoubleValue(RContractLine.TotalAmountOpen))));
    }
}

它在第 5 行给我一个错误:

局部变量 currentLateAmount在封闭作用域中定义的双精度必须是最终的或有效的最终的

Java 7 中的相同方法(有效):

BigDecimal currentLateAmountDouble = BigDecimal.ZERO;
Collection<VPO> lines = BO_Contract.getLines(trxName, contractVPO.getID(), RContractLine.LineNo + " ASC ", ctx);
if (lines != null && !lines.isEmpty()) {
    for (VPO line : lines) {
        if (onDate.compareTo(line.getDateValue(RContractLine.TermDate)) > 0) {
            currentLateAmountDouble = currentLateAmountDouble.add(NumberUtils.getAmount(line.getDoubleValue(RContractLine.TotalAmountOpen)));
        }
    }
}

编辑:解决了!使用@JBNizet解决方案并这样做:

currentLateAmountDouble = lines.stream().filter(line -> onDate.compareTo(line.getDateValue(RContractLine.TermDate)) > 0)
                .map(line -> NumberUtils.getAmount(line.getDoubleValue(RContractLine.TotalAmountOpen))).reduce(BigDecimal.ZERO, BigDecimal::add);

正如错误消息所说,您不能从 lambda 重新分配外部局部变量(就像在 Java 7 中从匿名类重新分配一样)。

尝试从功能操作修改外部状态是一种代码异味。但是您的操作只是一个映射,然后是归约操作:您将每个元素转换为 BigDecimal,然后将所有 BigDecimal 求和:

BigDecimal currentLateAmountDouble = 
   lines.stream()
        .map(line -> NumberUtils.getAmount(line.getDoubleValue(RContractLine.TotalAmountOpen)))
        .reduce(BigDecimal.ZERO, BigDecimal::add);

请注意,将 filter() 的结果与 null 进行比较的测试没有意义:filter()永远不会返回 null。您可能正在这里寻找anyMatch

你需要使用一个减少函数...

在您的 if 语句中尝试此操作...

currentLateAmountDouble  = lines.stream().mapToInt(l->NumberUtils.getAmount(l.getDoubleValue( RContractLine.TotalAmountOpen)).sum();

这可能不准确,我不是用电脑来测试这个,但应该让你足够接近。

另请参阅 https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html 以供参考

最新更新