Gatherer API


Introduced in Java 24, the Gatherer API is a powerful way to define custom intermediate operations in a Stream pipeline — something you couldn’t do easily before.

It’s like a customizable version of map(), filter(), and flatMap(), but with more control and state awareness.

Feature TraditionalStream Ops (map, filter, findFirst)Gatherer API
Custom intermediate opsLimitedFully customizable
Stateful processingLimitedSupported
Parallelism supportComplex, error-proneBuilt-in, optional combiner
Short-circuitingLimitedSupported
Incremental/asynchronousNoYes
Code simplicitySimple for basic ops, complex for customSimpler for complex custom ops
Transform infinite streamsDifficultSupported
  • Core Components of a Gatherer: A Gatherer transforms a stream of type T into a stream of type R. It has four main parts:
    • Initializer: Sets up any necessary state (such as a buffer or counter).
    • Integrator: Processes each element, possibly using the state, and decides whether to emit something downstream.
    • Combiner (optional): Merges states when processing in parallel.
    • Finisher (optional): Emits final results when the stream ends (like flushing a buffer).
  • Spliterator API V/s Gatherer API
    • Spliterator API
      • Supports parallelism but requires explicit splitting logic; can be tricky and error-prone.
      • Used under the hood by Stream API; not designed for direct user customization of intermediate ops.
    • Gatherer API
      • Built-in excellent parallelism support; even sequential gatherers can run in parallel streams, benefiting from parallelism.
      • Explicitly designed to be used with Stream.gather() for custom intermediate operations.

Reference

https://dev.java