在一个java流lambda函数中求和不同的值

ni *_*wen 1 java lambda java-8 java-stream

我有一个用例需要在这个对象中总结不同的字段,所以我这样编码,我可以把它放在一个流中吗?

int totalUnits = records.stream()
        .mapToInt(DynamoSalesAggregateSummaryRecord::getUnits).sum();
int totalReturns = records.stream()
        .mapToInt(DynamoSalesAggregateSummaryRecord::getReturns).sum();
int totalCancellations = records.stream()
        .mapToInt(DynamoSalesAggregateSummaryRecord::getCancellations).sum();
BigDecimal totalRevenue = records.stream()
        .map(DynamoSalesAggregateSummaryRecord::getRevenue)
        .reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalRoyalties = records.stream()
        .map(DynamoSalesAggregateSummaryRecord::getRoyalties)
        .reduce(BigDecimal.ZERO, BigDecimal::add);
Run Code Online (Sandbox Code Playgroud)

Gho*_*ica 5

老实说,我不会这样做.相反:首先摆脱代码重复:编写一个调用的小助手:

return records.stream().mapToInt(accessorMethod).sum();
Run Code Online (Sandbox Code Playgroud)

(将访问者传递给该方法的地方).

然后你可以去:

int totals = fetch(DynamoSalesAggregateSummaryRecord::getUnits) + fetch(DynamoSalesAggregateSummaryRecord::getReturns) + ...
Run Code Online (Sandbox Code Playgroud)

但除此之外 - 实际上并不清楚你打算在这里做什么.上面的示例假设您将构建所有条目的"总"总和.如果不是这种情况 - 而你想要"不同"的金额,我的建议就是放弃使用mapToInt().而是做一些像:

class SumHelper {
  private int unitTotals = 0;
  private int returnTotals = 0;
  ...

  public add(DynamoSalesAggregateSummaryRecord record) {
    unitTotals += record.getUnits();
    ...
Run Code Online (Sandbox Code Playgroud)

使用方式如下:

  SumHelper helper = new SumHelper;
  records.forEach(r -> helper.add(r));
Run Code Online (Sandbox Code Playgroud)

换句话说:您想要在记录上调用多个不同的方法; 建立不同的总和.你不能用流做 - 因为一个操作正在创建多个结果.所以你需要一些其他类型的"存储"来跟踪不同的结果.