Группировка по списку в результате - PullRequest
2 голосов
/ 26 марта 2020

У нас есть следующее:

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?

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

Это было бы невозможно, так как значение, которое вы ищете при сопоставлении с Balance объектами, может быть оценено только после итерации всех записей в списке MonthlyBalancedBooking.

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

Альтернативным способом перемещения потока в рамках одной операции терминала может быть использование collectingAndThen как:

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());
}
2 голосов
/ 26 марта 2020

Простой способ - просто использовать 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;
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...