Greetings,

As you may have already seen, Stream Gatherers is now a Preview JEP with 
Candidate status<https://openjdk.org/jeps/461>

Work-in-progress (interfaces, implementation, tests, benches, and 
documentation) for JEP-461 is currently available 
here<https://github.com/viktorklang-ora/jdk/tree/gatherer>.

While the design<https://cr.openjdk.org/~vklang/Gatherers.html> has held up 
well, there are some important improvements made since the original design 
document was written.

Notable changes (without any particular order):

  *   Stream::gather() now has a default implementation.

  *   Gatherer::supplier() was renamed to Gatherer::initializer() to better 
reflect intent.

  *   Gatherer.Sink<R> was renamed to Gatherer.Downstream<R> to better signal 
what it represents.

  *   Gatherer::collect(Collector) and its companion type 
Gatherer.ThenCollector was dropped due to compatibility concerns with existing 
code which operates on Collector.

  *
Gatherer.Characteristics have been eliminated and superseded by having default 
values that are used as sentinels.
 (discussed further down the list)
This is important because with the Characteristics-model keeping alignment 
between Characteristics and actual implementation proved brittle, and under 
composition of Gatherers computing the union was inefficient and mostly lead to 
an empty set in the end.

  *   Gatherer.defaultInitializer(), Gatherer.defaultCombiner(), and 
Gatherer.defaultFinisher() were added as static methods—these are the sentinels 
used to elide calling the initializer, to elide calling the combiner (avoid 
parallelization), and to elide calling the finisher, respectively.

  *   Gatherer::initializer(), Gatherer::combiner(), and Gatherer::finisher() 
default implementations return the respective sentinels.

  *   A subtype of Integrator named Greedy was added, together with a factory 
method to guide lambda-to-nominal-type conversion. This allows creators of 
Gatherers to signal that an Integrator will never initiate a short-circuit (but 
may relay one from downstream), and that is available during evaluation to 
determine if the operation can short-circuit or not.

  *   Factories for creating anonymous Gatherers were expanded upon to include 
Gatherer.of() and Gatherer.ofSequential() with different sets of parameters, 
primarily to make it more ergonomical and easier to read and write the code 
using those factories.

  *   A curated set of initial built-in Gatherers is located in 
java.util.stream.Gatherers

I recently presented Gatherers at 
Devoxx<https://www.youtube.com/watch?v=8fMFa6OqlY8>, which I'd recommend 
watching for an introduction to the feature.
[cid:d048f613-b144-4ff9-a2d3-98e0765aab57]<https://www.youtube.com/watch?v=8fMFa6OqlY8>
Teaching old Streams new tricks By Viktor 
Klang<https://www.youtube.com/watch?v=8fMFa6OqlY8>
Have you ever wanted to perform an operation on a java.util.stream.Stream only 
to find that the existing set of operations didn't provide what you 
needed—forcing you to break out early from the Stream and perform the logic 
outside of it? As a matter of fact, java.util.stream was the first JDK API 
designed with lambdas in mind and was ...
www.youtube.com
      

Cheers,
√


Viktor Klang
Software Architect, Java Platform Group
Oracle

Reply via email to