如何用Java Stream对对象列表多字段求和?语法错误排查
问题分析与修正
你的代码存在几个关键错误,导致编译失败:
1. reduce方法的参数类型不匹配
Stream.reduce的第二个参数是累加器函数,需要接收两个参数:
- 第一个是累加器(类型为
ProfitBalanceDto,即你定义的结果容器) - 第二个是流中的单个元素(类型为
BranchAccount)
而你写的(branchAccount1, branchAccount2)把两个参数都当成了BranchAccount,完全不符合reduce的参数要求。
2. ProfitBalanceDto缺少带参构造方法
你在代码中使用了new ProfitBalanceDto(0.0, 0.0)初始化累加器,但提供的ProfitBalanceDto类只有默认无参构造,没有接收两个Double的构造方法,这会直接导致编译错误。
3. 未返回reduce的计算结果
你最后直接return null,完全丢弃了reduce的计算结果,这不符合你的需求。
4. 实体类缺少字段的getter方法
BranchAccount和ProfitBalanceDto的私有字段没有对应的getter方法,在stream中无法访问accountBalance和profit的值,这也是编译报错的原因之一。
修正后的代码
第一步:完善ProfitBalanceDto
添加带参构造和getter(如果需要用collect方式还需添加setter):
public class ProfitBalanceDto { private Double accountBalance; private Double profit; // 带参构造方法 public ProfitBalanceDto(Double accountBalance, Double profit) { this.accountBalance = accountBalance; this.profit = profit; } // getter方法 public Double getAccountBalance() { return accountBalance; } public Double getProfit() { return profit; } // 可选:setter方法(如果使用collect方式需要) public void setAccountBalance(Double accountBalance) { this.accountBalance = accountBalance; } public void setProfit(Double profit) { this.profit = profit; } }
第二步:完善BranchAccount
添加字段的getter方法:
public class BranchAccount { @NotNull(message = "Account balance is required") private Double accountBalance; @NotNull(message = "Profit is required") private Double profit; @Temporal(TemporalType.TIMESTAMP) private Date dateCreated; @Temporal(TemporalType.TIMESTAMP) private Date lastUpdated; // getter方法 public Double getAccountBalance() { return accountBalance; } public Double getProfit() { return profit; } }
第三步:修正stream求和代码
方式1:使用reduce(每次创建新的Dto对象)
public ProfitBalanceDto getAllBranchAccount() { List<BranchAccount> branchAccounts = branchAccountRepository.findAll(); return branchAccounts.stream() .reduce(new ProfitBalanceDto(0.0, 0.0), (accumulator, branchAccount) -> new ProfitBalanceDto( accumulator.getAccountBalance() + branchAccount.getAccountBalance(), accumulator.getProfit() + branchAccount.getProfit() ) ); }
方式2:使用collect(更高效,复用同一个Dto对象)
public ProfitBalanceDto getAllBranchAccount() { return branchAccountRepository.findAll().stream() .collect(Collector.of( // 初始化累加器 () -> new ProfitBalanceDto(0.0, 0.0), // 处理单个元素 (acc, branchAccount) -> { acc.setAccountBalance(acc.getAccountBalance() + branchAccount.getAccountBalance()); acc.setProfit(acc.getProfit() + branchAccount.getProfit()); }, // 合并多个累加器(并行流场景需要) (acc1, acc2) -> { acc1.setAccountBalance(acc1.getAccountBalance() + acc2.getAccountBalance()); acc1.setProfit(acc1.getProfit() + acc2.getProfit()); return acc1; } )); }
内容的提问来源于stack exchange,提问作者Bille Ibinabo
相关产品推荐
相关产品推荐

