Лямбды и Потоки (Массив) - PullRequest
0 голосов
/ 12 июня 2018

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

У меня есть класс Invoiceгде есть название товара, цена и количество.Мне нужно сопоставить название товара и общую стоимость (цена * количество).

Хотя это не сработает, надеюсь, это даст представление о том, какая у меня проблема:

invoiceList.stream()
           .map(Invoice::getDesc)
           .forEach(System.out.println(Invoice::getPrice*Invoice::getQty));

Я уже могу сказать, что forEach не будет работать, поскольку он сопоставляется с описанием переменной (getDesc), а не с объектом Invoice, где я могу использовать его методы для получения других переменных.

Итак, если item=pencil, price=1, qty=12, вывод, который я хотел бы получить:

Pencil   12.00

Это будет сделано для нескольких объектов Invoice.

Кроме того, мне нужно отсортировать их по сумме, а также отфильтровать те, которые выше определенногосумма, например100. Как мне это сделать после размещения их на карте?

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Итак, во-первых, вот код, который, я думаю, вы пытались написать:

invoiceList.stream()
       .forEach(invoice -> System.out.println(invoice.getPrice() * invoice.getQty()));

Теперь давайте посмотрим, что здесь происходит:

Вызов .stream() в вашем списке создаетобъект, который имеет методы, доступные для выполнения операций над содержимым списка.foreach - это один такой метод, который вызывает функцию для каждого элемента.map - это еще один такой метод, но он возвращает другой поток, где содержимое - это содержимое вашего исходного потока, но каждый элемент заменяется возвращаемым значением функции, которую вы передаете на карту.

Есливы смотрите на внутреннюю часть вызова foreach, вы можете видеть лямбду.Это определяет анонимную функцию, которая будет вызываться для каждого элемента вашего invoiceList.Переменная invoice слева от символа -> привязана к каждому элементу потока, а выражение справа выполнено.

0 голосов
/ 12 июня 2018

если все, что вы хотите сделать, это распечатать на консоль, то это можно сделать следующим образом:

invoiceList.forEach(i -> System.out.println(i.getName() + "    " + (i.getPrice() * i.getQty())));

Если нет, тогда читайте дальше:

Использованиеколлектор toMap

Map<String, Double> result = 
     invoiceList.stream()
                .collect(Collectors.toMap(Invoice::getName, 
                                  e -> e.getPrice() * e.getQuantity()));

В основном создается карта, в которой ключами являются имена Invoice, а значения - это умножение цены и количества счета на данное значение Invoice.

Использование коллектора groupingBy

Однако, если может быть несколько счетов с одинаковым именем, вы можете использовать коллектор groupingBy вместе с summingDouble какнижестоящий коллектор:

Map<String, Double> result = 
     invoiceList.stream()
                .collect(groupingBy(Invoice::getName, 
                  Collectors.summingDouble(e -> e.getPrice() * e.getQuantity())));

Группирует Invoice по их именам, а затем для каждой группы суммирует результат e.getPrice() * e.getQuantity().


Обновление:

, если вы хотите, чтобы версия toMap и результат были отфильтрованы, а затем отсортированы по возрастанию значения, это можно сделать следующим образом:

Map<String, Double> result = invoiceList.stream()
            .filter(e -> e.getPrice() * e.getQuantity() > 100)
            .sorted(Comparator.comparingDouble(e -> e.getPrice() * e.getQuantity()))
            .collect(Collectors.toMap(Invoice::getName,
                    e -> e.getPrice() * e.getQuantity(), 
                    (left, right) -> left,
                    LinkedHashMap::new));

или с groupingBy подходом:

 Map<String, Double> result =
                invoiceList.stream()
                        .collect(groupingBy(Invoice::getName,
                                Collectors.summingDouble(e -> e.getPrice() * e.getQuantity())))
                        .entrySet()
                        .stream()
                        .filter(e -> e.getValue() > 100)
                        .sorted(Map.Entry.comparingByValue())
                        .collect(Collectors.toMap(Map.Entry::getKey,
                                Map.Entry::getValue, (left, right) -> left,
                                LinkedHashMap::new));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...