Spec-Zone.ru › OpenJDK 21

Interface Collector<T,A,R>

Параметры типа:
T - тип входных элементов для операции редукции
A - изменяемый тип накопления для операции редукции (часто скрывается как деталь реализации)
R - тип результата операции редукции
public interface Collector<T,A,R>
Операция изменяемой редукции, которая накапливает входные элементы в изменяемый контейнер результатов, необязательно преобразуя накопленный результат в конечное представление после обработки всех входных элементов. Операции редукции могут выполняться последовательно или параллельно.

Примеры операций изменяемой редукции включают: накопление элементов в Collection; конкатенация строк с помощью StringBuilder; вычисление сводной информации об элементах, таких как сумма, минимум, максимум или среднее значение; вычисление сводных таблиц, таких как «транзакция с максимальной стоимостью по продавцу» и т.д. Класс Collectors предоставляет реализации многих распространённых изменяемых редукций.

Collector определяется четырьмя функциями, которые совместно работают для накопления записей в изменяемый контейнер результатов и, необязательно, выполняют конечное преобразование результата. Это:

  • создание нового контейнера результатов (supplier())
  • включение нового элемента данных в контейнер результатов (accumulator())
  • объединение двух контейнеров результатов в один (combiner())
  • выполнение необязательного конечного преобразования контейнера (finisher())

Сборщики также имеют набор характеристик, таких как Collector.Characteristics.CONCURRENT, которые предоставляют подсказки, которые могут использоваться реализацией редукции для повышения производительности.

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

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

Ограничение тождества гласит, что для любого частично накопленного результата его объединение с пустым контейнером результатов должно давать эквивалентный результат. То есть, для частично накопленного результата a, который является результатом любой последовательности вызовов функций аккумулятора и объединения, a должен быть эквивалентен combiner.apply(a, supplier.get()).

Ограничение ассоциативности гласит, что разделение вычисления должно давать эквивалентный результат. То есть, для любых входных элементов t1 и t2, результаты r1 и r2 в вычислении ниже должны быть эквивалентны:


     A a1 = supplier.get();
     accumulator.accept(a1, t1);
     accumulator.accept(a1, t2);
     R r1 = finisher.apply(a1);  // result without splitting

     A a2 = supplier.get();
     accumulator.accept(a2, t1);
     A a3 = supplier.get();
     accumulator.accept(a3, t2);
     R r2 = finisher.apply(combiner.apply(a2, a3));  // result with splitting
  

Для сборщиков, которые не имеют характеристику UNORDERED, два накопленных результата a1 и a2 эквивалентны, если finisher.apply(a1).equals(finisher.apply(a2)). Для неупорядоченных сборщиков эквивалентность ослабляется, чтобы разрешить неравенство, связанное с различиями в порядке. (Например, неупорядоченный сборщик, который накапливал элементы в List , рассматривал бы два списка как эквивалентные, если бы они содержали одни и те же элементы, игнорируя порядок.)

Библиотеки, реализующие редукцию на основе Collector, такие как Stream.collect(Collector), должны соответствовать следующим ограничениям:

  • Первый аргумент, передаваемый функции аккумулятора, оба аргумента, передаваемые функции объединения, и аргумент, передаваемый функции завершения, должны быть результатом предыдущего вызова функций поставщика результата, аккумулятора или объединения.
  • Реализация не должна делать ничего с результатом любой из функций поставщика результатов, аккумулятора или объединения, кроме как передавать их снова функциям аккумулятора, объединения или завершения или возвращать их вызывающей стороне операции редукции.
  • Если результат передаётся функции объединения или завершения, и от этой функции возвращается другой объект, он больше никогда не используется.
  • После передачи результата функции объединения или завершения он больше никогда не передаётся функции аккумулятора.
  • Для неконкурентных сборщиков любой возвращаемый из функций поставщика результата, аккумулятора или объединения результат должен быть сериализованно ограничен потоком. Это позволяет производить сборку параллельно, не требуя от Collector реализации дополнительной синхронизации. Реализация редукции должна управлять тем, чтобы вход был правильно разделен, что разделы обрабатывались изолированно, а объединение происходило только после завершения накопления.
  • Для конкурентных сборщиков реализация свободна (но не обязана) реализовывать редукцию конкуретнно. Конкурентная редукция - это та, где функция аккумулятора вызывается параллельно из нескольких потоков, используя тот же изменяемый в нескольких потоках контейнер результатов, а не сохраняя результат изолированным во время накопления. Конкурентная редукция должна применяться только в том случае, если у сборщика есть характеристика Collector.Characteristics.UNORDERED или если исходные данные неупорядочены.

В дополнение к предопределённым реализациям в Collectors, статические методы-фабрики of(Supplier, BiConsumer, BinaryOperator, Characteristics...) могут использоваться для создания сборщиков. Например, вы можете создать сборщик, который накапливает виджеты в TreeSet:


     Collector<Widget, ?, TreeSet<Widget>> intoSet =
         Collector.of(TreeSet::new, TreeSet::add,
                      (left, right) -> { left.addAll(right); return left; });
 
(Это поведение также реализуется предопределённым сборщиком Collectors.toCollection(Supplier)).
Примечание API:
Выполнение операции редукции с Collector должно давать эквивалентный результат:

     A container = collector.supplier().get();
     for (T t : data)
         collector.accumulator().accept(container, t);
     return collector.finisher().apply(container);
 

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

Сборщики предназначены для композиции; многие методы в Collectors являются функциями, которые принимают сборщик и производят новый сборщик. Например, задан следующий сборщик, который вычисляет сумму зарплат потока сотрудников:


     Collector<Employee, ?, Integer> summingSalaries
         = Collectors.summingInt(Employee::getSalary))
 
Если нам нужно создать сборщик для подсчёта суммы зарплат по отделам, мы можем повторно использовать логику "суммы зарплат" с помощью Collectors.groupingBy(Function, Collector):

     Collector<Employee, ?, Map<Department, Integer>> summingSalariesByDept
         = Collectors.groupingBy(Employee::getDepartment, summingSalaries);
 
С:
1.8
См. также:
  • Stream.collect(Collector)
  • Collectors

Краткое описание вложенных классов

Модификатор и тип Интерфейс Описание
static enum  Collector.Characteristics
Характеристики, указывающие свойства Collector, которые могут использоваться для оптимизации реализаций редукции.

Краткое описание методов

Модификатор и тип Метод Описание
BiConsumer<A,T> accumulator()
Функция, которая складывает значение в изменяемый контейнер результата.
Set<Collector.Characteristics> characteristics()
Возвращает Set из Collector.Characteristics, указывающий характеристики этого сборщика.
BinaryOperator<A> combiner()
Функция, принимающая два частичных результата и сливающая их.
Function<A,R> finisher()
Выполняет конечное преобразование из промежуточного типа накопления A в конечный тип результата R.
static <T, A, R> Collector<T,A,R> of(Supplier<A> supplier, BiConsumer<A,T> accumulator, BinaryOperator<A> combiner, Function<A,R> finisher, Collector.Characteristics... characteristics)
Возвращает новый Collector, описанный заданными функциями supplier, accumulator, combiner и finisher.
static <T, R> Collector<T,R,R> of(Supplier<R> supplier, BiConsumer<R,T> accumulator, BinaryOperator<R> combiner, Collector.Characteristics... characteristics)
Возвращает новый Collector, описанный заданными функциями supplier, accumulator и combiner.
Supplier<A> supplier()
Функция, которая создаёт и возвращает новый изменяемый контейнер результата.

Подробное описание методов

supplier

Supplier<A> supplier()
Функция, которая создаёт и возвращает новый изменяемый контейнер результатов.
Возвращает:
функцию, возвращающую новый изменяемый контейнер результатов

accumulator

BiConsumer<A,T> accumulator()
Функция, которая складывает значение в изменяемый контейнер результатов.
Возвращает:
функцию, которая складывает значение в изменяемый контейнер результатов

combiner

BinaryOperator<A> combiner()
Функция, принимающая два частичных результата и объединяющая их. Функция combiner может складывать состояние из одного аргумента в другой и вернуть это, или может вернуть новый контейнер результатов.
Возвращает:
функцию, объединяющую два частичных результата в объединённый результат

finisher

Function<A,R> finisher()
Выполняет окончательное преобразование из промежуточного типа накопления A в конечный тип результата R.

Если характеристика IDENTITY_FINISH установлена, можно предположить, что эта функция является тождественным преобразованием с непроверенным приведением типов от A к R.

Возвращает:
функцию, преобразующую промежуточный результат в конечный результат

characteristics

Set<Collector.Characteristics> characteristics()
Возвращает Set Collector.Characteristics , указывающую характеристики этого Collector. Этот набор должен быть неизменяемым.
Возвращает:
неизменяемый набор характеристик коллектора

of

static <T, R> Collector<T,R,R> of(Supplier<R> supplier, BiConsumer<R,T> accumulator, BinaryOperator<R> combiner, Collector.Characteristics... characteristics)
Возвращает новый Collector , описываемый заданными supplier, accumulator, и combiner функциями. Результирующий Collector имеет характеристику Collector.Characteristics.IDENTITY_FINISH.
Параметры типа:
T - Тип входных элементов для нового коллектора
R - Тип промежуточного результата накопления и конечного результата для нового коллектора
Параметры:
supplier - Функция поставщика для нового коллектора
accumulator - Функция накопителя для нового коллектора
combiner - Функция объединения для нового коллектора
characteristics - Характеристики коллектора для нового коллектора
Возвращает:
новый Collector
Исключения:
NullPointerException - если какой-либо аргумент равен null

of

static <T, A, R> Collector<T,A,R> of(Supplier<A> supplier, BiConsumer<A,T> accumulator, BinaryOperator<A> combiner, Function<A,R> finisher, Collector.Characteristics... characteristics)
Возвращает новый Collector , описываемый заданными supplier, accumulator, combiner, и finisher функциями.
Параметры типа:
T - Тип входных элементов для нового коллектора
A - Промежуточный тип накопления нового коллектора
R - Конечный тип результата нового коллектора
Параметры:
supplier - Функция поставщика для нового коллектора
accumulator - Функция накопителя для нового коллектора
combiner - Функция объединения для нового коллектора
finisher - Функция завершения для нового коллектора
characteristics - Характеристики коллектора для нового коллектора
Возвращает:
новый Collector
Исключения:
NullPointerException - если какой-либо аргумент равен null

© 1993, 2023, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/Collector.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API