Preview
Second Preview of Stream Gatherers (JEP 473).
Programs can only use Gatherer
when preview features are enabled.
Preview features may be removed in a future release,
or upgraded to permanent features of the Java platform.
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
java.
provides implementations of common
gathering operations.
API Note
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
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
java.
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();
Implementation Specification
Libraries that implement transformations based on Gatherer
,
such as Stream#gather(Gatherer)
, must adhere to the following
constraints:
defaultInitializer()
are
considered to be stateless, and invoking their initializer is optional.
Integrator.Greedy
can be assumed not to short-circuit, and the return value of invoking
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.Stream#gather(Gatherer)
, Gatherers
Modifier and Type | Class and Description |
---|---|
public static interface | Gatherer.
the type of elements this downstream accepts T>
Preview
Second Preview of Stream Gatherers (JEP 473).
A Downstream object is the next stage in a pipeline of operations,
to which elements can be sent.
|
public static interface | Gatherer.
the type of state used by this integrator A, the type of elements this integrator consumes T, the type of results this integrator can produce R>
Preview
Second Preview of Stream Gatherers (JEP 473).
An Integrator receives elements and processes them,
optionally using the supplied state, and optionally sends incremental
results downstream.
|
Modifier and Type | Method and Description |
---|---|
public default < The type of output of that Gatherer RR> Gatherer | |
public default BinaryOperator | Returns: a function which accepts two intermediate states and combines them into oneA function which accepts two intermediate states and combines them into one. |
public static < the type of the state of the returned combiner A> BinaryOperator | Returns: the instance of the default combinerReturns a combiner which is the default combiner of a Gatherer. |
public static < the type of the state of the returned finisher A, the type of the Downstream of the returned finisher R> BiConsumer | Returns: the instance of the default finisherReturns a |
public static < the type of the state of the returned initializer A> Supplier | Returns: the instance of the default initializerReturns an initializer which is the default initializer of a Gatherer. |
public default BiConsumer | Returns: a function which transforms the intermediate result to the final result(s) which are then passed on to the provided DownstreamA function which accepts the final intermediate state
and a |
public default Supplier | Returns: A function that produces an instance of the intermediate state used for this gathering operationA function that produces an instance of the intermediate state used for this gathering operation. |
public Gatherer. | Returns: a function which integrates provided elements, potentially using the provided state, optionally producing output to the provided DownstreamA function which integrates provided elements, potentially using
the provided intermediate state, optionally producing output to the
provided |
public static < the type of input elements for the new gatherer T, the type of results for the new gatherer R> Gatherer | Returns: the newGatherer the integrator function for the new gatherer integratorReturns a new, parallelizable, and stateless |
public static < the type of input elements for the new gatherer T, the type of results for the new gatherer R> Gatherer | Returns: the newGatherer the integrator function for the new gatherer integrator,the finisher function for the new gatherer finisherReturns a new, parallelizable, and stateless |
public static < the type of input elements for the new gatherer T, the type of state for the new gatherer A, the type of results for the new gatherer R> Gatherer | Returns: the newGatherer the initializer function for the new gatherer initializer, Gatherer.the integrator function for the new gatherer integrator,the combiner function for the new gatherer combiner, BiConsumer<A, Gatherer.the finisher function for the new gatherer finisherReturns a new, parallelizable, |
public static < the type of input elements for the new gatherer T, the type of results for the new gatherer R> Gatherer | Returns: the newGatherer the integrator function for the new gatherer integratorReturns a new, sequential, and stateless |
public static < the type of input elements for the new gatherer T, the type of results for the new gatherer R> Gatherer | Returns: the newGatherer the integrator function for the new gatherer integrator,the finisher function for the new gatherer finisherReturns a new, sequential, and stateless |
public static < the type of input elements for the new gatherer T, the type of state for the new gatherer A, the type of results for the new gatherer R> Gatherer | Returns: the newGatherer the initializer function for the new gatherer initializer, Gatherer.the integrator function for the new gatherer integratorReturns a new, sequential, |
public static < the type of input elements for the new gatherer T, the type of state for the new gatherer A, the type of results for the new gatherer R> Gatherer | Returns: the newGatherer the initializer function for the new gatherer initializer, Gatherer.the integrator function for the new gatherer integrator,the finisher function for the new gatherer finisherReturns a new, sequential, |
andThen | back to summary |
---|---|
public default <RR> Gatherer Returns a composed Gatherer which connects the output of this Gatherer to the input of that Gatherer. Implementation Specification The implementation in this interface returns a new Gatherer
which is semantically equivalent to the combination of
|
combiner | back to summary |
---|---|
public default BinaryOperator A function which accepts two intermediate states and combines them into one. Implementation Specification The implementation in this interface returns
|
defaultCombiner | back to summary |
---|---|
public static <A> BinaryOperator Returns a combiner which is the default combiner of a Gatherer. The returned combiner identifies that the owning Gatherer must only be evaluated sequentially. Implementation Specification This method always returns the same instance.
|
defaultFinisher | back to summary |
---|---|
public static <A, R> BiConsumer Returns a Implementation Specification This method always returns the same instance.
|
defaultInitializer | back to summary |
---|---|
public static <A> Supplier Returns an initializer which is the default initializer of a Gatherer. The returned initializer identifies that the owner Gatherer is stateless. Implementation Specification This method always returns the same instance.
|
finisher | back to summary |
---|---|
public default BiConsumer A function which accepts the final intermediate state
and a Implementation Specification The implementation in this interface returns
|
initializer | back to summary |
---|---|
public default Supplier A function that produces an instance of the intermediate state used for this gathering operation. Implementation Specification The implementation in this interface returns
|
integrator | back to summary |
---|---|
public Gatherer. A function which integrates provided elements, potentially using
the provided intermediate state, optionally producing output to the
provided
|
of | back to summary |
---|---|
public static <T, R> Gatherer Returns a new, parallelizable, and stateless
|
of | back to summary |
---|---|
public static <T, R> Gatherer Returns a new, parallelizable, and stateless
|
of | back to summary |
---|---|
public static <T, A, R> Gatherer Returns a new, parallelizable,
|
ofSequential | back to summary |
---|---|
public static <T, R> Gatherer Returns a new, sequential, and stateless
|
ofSequential | back to summary |
---|---|
public static <T, R> Gatherer Returns a new, sequential, and stateless
|
ofSequential | back to summary |
---|---|
public static <T, A, R> Gatherer Returns a new, sequential,
|
ofSequential | back to summary |
---|---|
public static <T, A, R> Gatherer Returns a new, sequential,
|
Preview
Second Preview of Stream Gatherers (JEP 473).
Programs can only use Downstream
when preview features are enabled.
Preview features may be removed in a future release,
or upgraded to permanent features of the Java platform.
Modifier and Type | Method and Description |
---|---|
public default boolean | Returns: true if this Downstream is known not to want any
more elements sent to it, false if otherwiseChecks whether the next stage is known to not want any more elements sent to it. |
public boolean | Returns: true if more elements can be sent,
and false if not.the element to push downstream element)Pushes, if possible, the provided element downstream -- to the next stage in the pipeline. |
isRejecting | back to summary |
---|---|
public default boolean isRejecting() Checks whether the next stage is known to not want any more elements sent to it. API Note This is best-effort only, once this returns Implementation Specification The implementation in this interface returns
|
push | back to summary |
---|---|
public boolean push(T element) Pushes, if possible, the provided element downstream -- to the next stage in the pipeline. Implementation Specification If this method returns
|
Preview
Second Preview of Stream Gatherers (JEP 473).
Programs can only use Integrator
when preview features are enabled.
Preview features may be removed in a future release,
or upgraded to permanent features of the Java platform.
Modifier and Type | Class and Description |
---|---|
public static interface | Gatherer.
the type of state used by this integrator A, the type of elements this greedy integrator receives T, the type of results this greedy integrator can produce R>
Preview
Second Preview of Stream Gatherers (JEP 473).
Greedy Integrators consume all their input, and may only relay that
the downstream does not want more elements.
|
Modifier and Type | Method and Description |
---|---|
public boolean | Returns: true if subsequent integration is desired,
false if notThe state to integrate into state, T The element to integrate element, Gatherer.The downstream object of this integration downstreamPerforms an action given: the current state, the next element, and a downstream object; potentially inspecting and/or updating the state, optionally sending any number of elements downstream -- and then returns whether more elements are to be consumed or not. |
public static < the type of state used by this integrator A, the type of elements this integrator receives T, the type of results this integrator can produce R> Gatherer. | Returns: the given lambda as an Integratora lambda to create as Integrator integratorFactory method for turning Integrator-shaped lambdas into Integrators. |
public static < the type of state used by this integrator A, the type of elements this integrator receives T, the type of results this integrator can produce R> Gatherer. | Returns: the given lambda as a Greedy Integratora lambda to create as Integrator.Greedy greedyFactory method for turning Integrator-shaped lambdas into
|
integrate | back to summary |
---|---|
public boolean integrate(A state, T element, Gatherer. Performs an action given: the current state, the next element, and a downstream object; potentially inspecting and/or updating the state, optionally sending any number of elements downstream -- and then returns whether more elements are to be consumed or not.
|
of | back to summary |
---|---|
public static <A, T, R> Gatherer. Factory method for turning Integrator-shaped lambdas into Integrators.
|
ofGreedy | back to summary |
---|---|
public static <A, T, R> Gatherer. Factory method for turning Integrator-shaped lambdas into
|
Preview
Second Preview of Stream Gatherers (JEP 473).
Programs can only use Greedy
when preview features are enabled.
Preview features may be removed in a future release,
or upgraded to permanent features of the Java platform.
Implementation Specification
This interface is used to communicate that no short-circuiting will be initiated by this Integrator, and that information can then be used to optimize evaluation.