T - the type of input elements to the gatherer operationA - the potentially mutable state type of the gatherer operation (often hidden as an implementation detail)R - the type of output elements from the gatherer operationpublic interface Gatherer<T,A,R>
Gatherer operations can be performed either sequentially, or be parallelized -- if a combiner function is supplied.
There are many examples of gathering operations, including but not limited to: grouping elements into batches (windowing functions); de-duplicating consecutively similar elements; incremental accumulation functions (prefix scan); incremental reordering functions, etc. The class Gatherers provides implementations of common gathering operations.
A Gatherer is specified by four functions that work together to process input elements, optionally using intermediate state, and optionally perform a final action at the end of input. They are:
initializer())integrator())combiner())finisher())Each invocation of initializer(), integrator(), combiner(), and finisher() must return a semantically identical result.
Implementations of Gatherer must not capture, retain, or expose to other threads, the references to the state instance, or the downstream Gatherer.Downstream for longer than the invocation duration of the method which they are passed to.
Performing a gathering operation with a Gatherer should produce a result equivalent to:
Gatherer.Downstream<? super R> downstream = ...;
A state = gatherer.initializer().get();
for (T t : data) {
gatherer.integrator().integrate(state, t, downstream);
}
gatherer.finisher().accept(state, downstream);
However, the library is free to partition the input, perform the integrations on the partitions, and then use the combiner function to combine the partial results to achieve a gathering operation. (Depending on the specific gathering operation, this may perform better or worse, depending on the relative cost of the integrator and combiner functions.)
In addition to the predefined implementations in Gatherers, the static factory methods of(...) and ofSequential(...) can be used to construct gatherers. For example, you could create a gatherer that implements the equivalent of Stream.map(java.util.function.Function) with:
public static <T, R> Gatherer<T, ?, R> map(Function<? super T, ? extends R> mapper) {
return Gatherer.of(
(unused, element, downstream) -> // integrator
downstream.push(mapper.apply(element))
);
}
Gatherers are designed to be composed; two or more Gatherers can be composed into a single Gatherer using the andThen(Gatherer) method.
// using the implementation of `map` as seen above
Gatherer<Integer, ?, Integer> increment = map(i -> i + 1);
Gatherer<Object, ?, String> toString = map(i -> i.toString());
Gatherer<Integer, ?, String> incrementThenToString = increment.andThen(toString);
As an example, a Gatherer implementing a sequential Prefix Scan could be done the following way:
public static <T, R> Gatherer<T, ?, R> scan(
Supplier<R> initial,
BiFunction<? super R, ? super T, ? extends R> scanner) {
class State {
R current = initial.get();
}
return Gatherer.<T, State, R>ofSequential(
State::new,
Gatherer.Integrator.ofGreedy((state, element, downstream) -> {
state.current = scanner.apply(state.current, element);
return downstream.push(state.current);
})
);
}
Example of usage:
// will contain: ["1", "12", "123", "1234", "12345", "123456", "1234567", "12345678", "123456789"]
List<String> numberStrings =
Stream.of(1,2,3,4,5,6,7,8,9)
.gather(
scan(() -> "", (string, number) -> string + number)
)
.toList();
Gatherer, such as Stream.gather(Gatherer), must adhere to the following constraints: defaultInitializer() are considered to be stateless, and invoking their initializer is optional. Gatherer.Integrator.Greedy can be assumed not to short-circuit, and the return value of invoking Gatherer.Integrator.integrate(Object, Object, Downstream) does not need to be inspected.false, it shall be interpreted just as if there were no more elements to pass it.defaultCombiner() may only be evaluated sequentially. All other combiners allow the operation to be parallelized by initializing each partition in separation, invoking the integrator until it returns false, and then joining each partitions state using the combiner, and then invoking the finisher on the joined state. Outputs and state later in the input sequence will be discarded if processing an earlier partition short-circuits.defaultFinisher() are considered to not have an end-of-stream hook and invoking their finisher is optional.| Modifier and Type | Interface | Description |
|---|---|---|
static interface |
Gatherer.Downstream<T> |
A Downstream object is the next stage in a pipeline of operations, to which elements can be sent. |
static interface |
Gatherer.Integrator<A, |
An Integrator receives elements and processes them, optionally using the supplied state, and optionally sends incremental results downstream. |
| Modifier and Type | Method | Description |
|---|---|---|
default <RR> Gatherer |
andThen |
Returns a composed Gatherer which connects the output of this Gatherer to the input of that Gatherer. |
default BinaryOperator |
combiner() |
A function which accepts two intermediate states and combines them into one. |
static <A> BinaryOperator |
defaultCombiner() |
Returns a combiner which is the default combiner of a Gatherer. |
static <A, |
defaultFinisher() |
Returns a finisher which is the default finisher of a Gatherer. |
static <A> Supplier |
defaultInitializer() |
Returns an initializer which is the default initializer of a Gatherer. |
default BiConsumer |
finisher() |
A function which accepts the final intermediate state and a Gatherer.Downstream object, allowing to perform a final action at the end of input elements. |
default Supplier |
initializer() |
A function that produces an instance of the intermediate state used for this gathering operation. |
Gatherer.Integrator |
integrator() |
A function which integrates provided elements, potentially using the provided intermediate state, optionally producing output to the provided Gatherer.Downstream. |
static <T, |
of |
Returns a new, parallelizable, Gatherer described by the given initializer, integrator, combiner and finisher. |
static <T, |
of |
Returns a new, parallelizable, and stateless Gatherer described by the given integrator. |
static <T, |
of |
Returns a new, parallelizable, and stateless Gatherer described by the given integrator and finisher. |
static <T, |
ofSequential |
Returns a new, sequential, Gatherer described by the given initializer and integrator. |
static <T, |
ofSequential |
Returns a new, sequential, Gatherer described by the given initializer, integrator, and finisher. |
static <T, |
ofSequential |
Returns a new, sequential, and stateless Gatherer described by the given integrator. |
static <T, |
ofSequential |
Returns a new, sequential, and stateless Gatherer described by the given integrator and finisher. |
default Supplier<A> initializer()
defaultInitializer().Gatherer.Integrator<A,T,R> integrator()
Gatherer.Downstream.default BinaryOperator<A> combiner()
defaultCombiner().default BiConsumer<A, Gatherer.Downstream<? super R>> finisher()
Gatherer.Downstream object, allowing to perform a final action at the end of input elements.defaultFinisher().default <RR> Gatherer<T,?,RR> andThen(Gatherer<? super R, ?, ? extends RR> that)
this and that gatherer.RR - The type of output of that Gathererthat - the other gathererNullPointerException - if the argument is null
static <A> Supplier<A> defaultInitializer()
A - the type of the state of the returned initializerstatic <A> BinaryOperator<A> defaultCombiner()
A - the type of the state of the returned combinerstatic <A,R> BiConsumer<A, Gatherer.Downstream<? super R>> defaultFinisher()
finisher which is the default finisher of a Gatherer. The returned finisher identifies that the owning Gatherer performs no additional actions at the end of input.A - the type of the state of the returned finisherR - the type of the Downstream of the returned finisherstatic <T,R> Gatherer<T,Void,R> ofSequential(Gatherer.Integrator<Void,T,R> integrator)
Gatherer described by the given integrator.T - the type of input elements for the new gathererR - the type of results for the new gathererintegrator - the integrator function for the new gathererGatherer
NullPointerException - if the argument is null
static <T,R> Gatherer<T,Void,R> ofSequential(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, Gatherer.Downstream<? super R>> finisher)
Gatherer described by the given integrator and finisher.T - the type of input elements for the new gathererR - the type of results for the new gathererintegrator - the integrator function for the new gathererfinisher - the finisher function for the new gathererGatherer
NullPointerException - if any argument is null
static <T,A,R> Gatherer<T,A,R> ofSequential(Supplier<A> initializer, Gatherer.Integrator<A,T,R> integrator)
Gatherer described by the given initializer and integrator.T - the type of input elements for the new gathererA - the type of state for the new gathererR - the type of results for the new gathererinitializer - the initializer function for the new gathererintegrator - the integrator function for the new gathererGatherer
NullPointerException - if any argument is null
static <T,A,R> Gatherer<T,A,R> ofSequential(Supplier<A> initializer, Gatherer.Integrator<A,T,R> integrator, BiConsumer<A, Gatherer.Downstream<? super R>> finisher)
Gatherer described by the given initializer, integrator, and finisher.T - the type of input elements for the new gathererA - the type of state for the new gathererR - the type of results for the new gathererinitializer - the initializer function for the new gathererintegrator - the integrator function for the new gathererfinisher - the finisher function for the new gathererGatherer
NullPointerException - if any argument is null
static <T,R> Gatherer<T,Void,R> of(Gatherer.Integrator<Void,T,R> integrator)
Gatherer described by the given integrator.T - the type of input elements for the new gathererR - the type of results for the new gathererintegrator - the integrator function for the new gathererGatherer
NullPointerException - if any argument is null
static <T,R> Gatherer<T,Void,R> of(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, Gatherer.Downstream<? super R>> finisher)
Gatherer described by the given integrator and finisher.T - the type of input elements for the new gathererR - the type of results for the new gathererintegrator - the integrator function for the new gathererfinisher - the finisher function for the new gathererGatherer
NullPointerException - if any argument is null
static <T,A,R> Gatherer<T,A,R> of(Supplier<A> initializer, Gatherer.Integrator<A,T,R> integrator, BinaryOperator<A> combiner, BiConsumer<A, Gatherer.Downstream<? super R>> finisher)
Gatherer described by the given initializer, integrator, combiner and finisher.T - the type of input elements for the new gathererA - the type of state for the new gathererR - the type of results for the new gathererinitializer - the initializer function for the new gathererintegrator - the integrator function for the new gatherercombiner - the combiner function for the new gathererfinisher - the finisher function for the new gathererGatherer
NullPointerException - if any argument is null
© 1993, 2025, 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/25/docs/api/java.base/java/util/stream/Gatherer.html