На прошлой неделе я описал вариант использования для пользовательского потока Collector
. Я получил интригующий комментарий в Твиттере:
Снимаю шляпу перед тобой, Мигель! Ваш комментарий раскрыл метод, которого я не знал!
Поэтому я решил выяснить, что представляет собой метод teeing()
.
Возвращает коллектор, состоящий из двух нижестоящих коллекторов. Каждый элемент, переданный результирующему сборщику, обрабатывается обоими нижестоящими сборщиками, затем их результаты объединяются с помощью указанной функции слияния в конечный результат.
Результирующие функции сборщика выполняют следующее:
- поставщик: создает результирующий контейнер, содержащий результирующие контейнеры, полученные путем вызова поставщика каждого сборщика
- накопитель: вызывает накопитель каждого коллектора с его контейнером результатов и элементом ввода
- объединитель: вызывает объединитель каждого сборщика с двумя контейнерами результатов
- финишер: вызывает финишер каждого сборщика с его контейнером результатов, затем вызывает предоставленное слияние и возвращает его результат.
— JavaDocs
Мы действительно можем заменить наш пользовательский Collector
двумя простыми реализациями Collector
, одна из которых объединяет строки цен, а другая суммирует цену корзины.
Давайте посмотрим на окончательный код и объясним его построчно.
public PriceAndRows getPriceAndRows(Cart cart) { return cart.getProducts() .entrySet() .stream() .map(CartRow::new) // 1 .collect(Collectors.teeing( // 2 Collectors.reducing( // 3 BigDecimal.ZERO, // 3.1 CartRow::getRowPrice, // 3.2 BigDecimal::add), // 3.3 Collectors.toList(), // 4 PriceAndRows::new // 5 )); }
- Нанесите на карту каждый
Запись
вСтроку корзины
- Вызовите метод
teeing()
Первый сборщик вычисляет цену. Это простой вызов
reducing()
с:- Начальный элемент
- Функция для извлечения
Цены
изстроки корзины
-
Бинарный оператор
для сложения двух цен вместе
Второй сборщик объединяет строку
корзины
в списокНаконец, последний параметр создает новый объект, который объединяет результаты первого и второй коллекционер
На стороне реализации, teeing()
:
- Извлекает каждый из отдельных компонентов обоих
Коллектора
, т.е. ,поставщика(),
аккумулятора(),
объединителя()и
готово()` - Соединяет их бок о бок
- Создает один новый
Коллектор
путем передачи пар
Таким образом, будет один Коллектор
и один проход в конце.
Я надеюсь, что этот пост заставил вас рассмотреть возможность использования teeing()
перед созданием пользовательского коллектора
. Еще раз спасибо Мигелю!
Кстати, я всегда рад узнавать что-то новое. Если вам есть чем поделиться, вы можете воспользоваться приведенной ниже системой комментариев или Twitter.
Полный исходный код для этого поста можно найти на Github в формате Maven. Проверьте ветку teeing
:
java-гик/пользователь-коллекционер
Чтобы идти дальше:
Первоначально опубликовано на Фанат Java 9 мая th , 2021
Оригинал: “https://dev.to/nfrankel/teeing-a-hidden-gem-in-the-java-api-1cnj”