2

我们有以下内容:

public List<Balance> mapToBalancesWithSumAmounts(List<MonthlyBalancedBooking> entries) {
    return entries
      .stream()
      .collect(
        groupingBy(
          MonthlyBalancedBooking::getValidFor,
          summingDouble(MonthlyBalancedBooking::getAmount)
        )
      )
      .entrySet()
      .stream()
      .map(localDateDoubleEntry -> new Balance(localDateDoubleEntry.getValue(), localDateDoubleEntry.getKey()))
      .collect(toList());
  }

是否有可能避免代码中的第二个 stream() 路径,所以 groupingBy() 的结果在我们的例子中应该是一个列表。我们需要传递 map() 函数来收集或分组的可能性,这在 Java 8 中可能吗?

4

2 回答 2

2

简单的方法就是使用toMap()带有合并功能的收集器,如下所示:

List<Balance> balances = new ArrayList<>(entries.stream()
       .collect(toMap(MonthlyBalancedBooking::getValidFor, m -> new Balance(m.getAmount(),
                                              m.getValidFor()),Balance::merge)).values());

我想为Balance类这些属性:

class Balance {
   private Double value;
   private Integer key;

   public Balance merge(Balance b) {
     this.value += b.getValue();
     return this;
   }
}
于 2020-03-26T07:32:06.197 回答
2

这是不可能的,因为只有在迭代列表的Balance所有条目后才能评估映射到对象时要查找的值。MonthlyBalancedBooking

new Balance(localDateDoubleEntry.getValue(), localDateDoubleEntry.getKey())

在单个终端操作中移动流的另一种方法是使用collectingAndThenas:

public List<Balance> mapToBalancesWithSumAmounts(List<MonthlyBalancedBooking> entries) {
    return entries.stream()
            .collect(Collectors.collectingAndThen(
                    Collectors.groupingBy(MonthlyBalancedBooking::getValidFor,
                            Collectors.summingDouble(MonthlyBalancedBooking::getAmount)),
                    map -> map.entrySet().stream()
                            .map(entry -> new Balance(entry.getValue(), entry.getKey()))))
            .collect(Collectors.toList());
}
于 2020-03-26T08:27:06.807 回答