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