Рубрики
Без рубрики

Видите ли, скрытая жемчужина в Java API

На прошлой неделе я описал пример использования пользовательского сборщика потоков. Я получил интригующий комментарий о Т… С тегами java, stream, api, teeing.

На прошлой неделе я описал вариант использования для пользовательского потока 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
      ));
}
  1. Нанесите на карту каждый Запись в Строку корзины
  2. Вызовите метод teeing()
  3. Первый сборщик вычисляет цену. Это простой вызов reducing() с:

    1. Начальный элемент
    2. Функция для извлечения Цены из строки корзины
    3. Бинарный оператор для сложения двух цен вместе
  4. Второй сборщик объединяет строку корзины в список

  5. Наконец, последний параметр создает новый объект, который объединяет результаты первого и второй коллекционер

На стороне реализации, teeing() :

  1. Извлекает каждый из отдельных компонентов обоих Коллектора , т.е. , поставщика(), аккумулятора() , объединителя() и готово()`
  2. Соединяет их бок о бок
  3. Создает один новый Коллектор путем передачи пар

Таким образом, будет один Коллектор и один проход в конце.

Я надеюсь, что этот пост заставил вас рассмотреть возможность использования teeing() перед созданием пользовательского коллектора . Еще раз спасибо Мигелю!

Кстати, я всегда рад узнавать что-то новое. Если вам есть чем поделиться, вы можете воспользоваться приведенной ниже системой комментариев или Twitter.

Полный исходный код для этого поста можно найти на Github в формате Maven. Проверьте ветку teeing :

java-гик/пользователь-коллекционер

Чтобы идти дальше:

Первоначально опубликовано на Фанат Java 9 мая th , 2021

Оригинал: “https://dev.to/nfrankel/teeing-a-hidden-gem-in-the-java-api-1cnj”