Суммирование значений объекта путем первой фильтрации других уникальных значений того же объекта - PullRequest
0 голосов
/ 31 мая 2019

Допустим, у меня есть список объекта, который можно назвать объектом Order, который имеет количество и цену в виде полей.

например, как показано ниже:

Список

Объект Order (поля quantity и price) содержит следующие значения:

Quantity  Price

5         200
6         100
3         200
1         300

Теперь я хочу использовать Java-8 для извлечения этого списка, отфильтрованного ниже:

Quantity  Price

8         200
6         100
1         300

Цена, являющаяся уникальным значением для фильтрации и суммирования любого количества, которое имеет цена, я хочу сформировать новый список на основе этого.

Пожалуйста, предложите, как я могу сделать это с лямбда-выражением Java 8, спасибо.

1 Ответ

9 голосов
/ 31 мая 2019

Следующее Stream делает трюк:

List<Order> o  = orders.stream().collect(
    Collectors.collectingAndThen(
        Collectors.groupingBy(Order::getPrice,Collectors.summingInt(Order::getQuantity)),
        map -> map.entrySet().stream()
                             .map(e -> new Order(e.getKey(), e.getValue()))
                             .collect(Collectors.toList())));

Давайте разберем это:

  1. Следующий код возвращает Map<Integer, Integer>, который содержит цену какключ (уникальное значение, на котором вы хотите основать суммирование) и его суммируемые количества.Ключевым методом является Collectors.groupingBy с classifier, описывающим ключ, и downstream, определяющим значение, которое будет суммой величин, следовательно, Collectors.summingInt (зависит оттип quantity):

    Map<Integer, Integer> map = orders.stream().collect(
        Collectors.groupingBy(                            // I want a Map<Integer, Integer>
            Order::getPrice,                              // price is the key
            Collectors.summingInt(Order::getQuantity))    // sum of quantities is the value
    
  2. Желаемая структура List<Order>, поэтому вы хотите использовать метод Collectors.collectingAndThen с Collector<T, A, R> downstream и Function<R, RR> finisher.downstream - это группировка с первой точки, финишером будет преобразование Map<Integer, Integer> обратно в List<Order>:

    List<Order> o  = orders.stream().collect(
    Collectors.collectingAndThen(
        grouping,                                                 // you know this one ;)
        map -> map.entrySet()                        
                  .stream()                                       // iterate entries
                  .map(e -> new Order(e.getKey(), e.getValue()))  // new Order(qty, price)
                  .collect(Collectors.toList())));                // as a List<Order>
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...