Gatherer JavaDoc
Viktor Klang
viktor.klang at oracle.com
Thu Jun 19 12:35:54 UTC 2025
Hi Cay!
Thanks for the questions, see my responses below:
>1. "Gatherers whose integrator is an instance of 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*."
>The way it is worded, I get the impression that a greedy integrator could simply >return false (or to save a letter, true), because, not inspected. But I am confused. It >was my impression that any integrator, greedy or not, should return false if >downstream.push returns false. Why would the implementation not want to >know? (The current implementation does inspect the return value.)
No, it doesn't say that it won't be inspected, it says that it doesn't need to. So if a user returns false from a greedy integrator's integrate-method, they can't be surprised if that signal isn't acted upon.
The "evaluator" which operates on the Gatherer instance then has more freedom as to how it is implemented when it sees Greedy Integrators.
>2. "Gatherers whose finisher is defaultFinisher() are considered to not have an >end-of-stream hook *and invoking their finisher is optional.*"
>I don't get the significance of the "and" part. Why would anyone care if >defaultFinisher is invoked? It's a no-op.
For developers: If the user has to implement the Gatherer interface and overrides/implements the finisher()-method, it does not need to synthesize a no-op (bi-)consumer, which will end up being invoked needlessly, but instead they can return the `defaultFinisher()` which indeed is how the default implementation of Gatherer::finisher() is implemented: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherer.java#L250
For developers who venture into overriding andThen(), knowing which finishers are no-ops, and thus do not need to be composed, reduces the cost of invoking them.
For implementors of things which evaluate Gatherers: they can now avoid the overhead of invoking no-op finishers (which tend to be fairly common).
>3. What is the use case for
>static <T,R> Gatherer<T,Void,R>
>of(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, >Gatherer.Downstream<? super R>> finisher)
>If there is no state, what can the finisher do?
Inject known data at the end of a stream, for instance:
jshell> Gatherer<String, Void, String> s = Gatherer.of((_, s, d) -> d.push(s), (_, d) -> d.push("EOF"))
s ==> GathererImpl[initializer=DEFAULT, integrator=$Lam ... 0000007e000cf838 at 5f3a4b84]
jshell> Stream.of("foo", "bar", "baz").gather(s).toList()
$2 ==> [foo, bar, baz, EOF]
Cheers,
√
Viktor Klang
Software Architect, Java Platform Group
Oracle
________________________________
From: core-libs-dev <core-libs-dev-retn at openjdk.org> on behalf of Cay Horstmann <cay.horstmann at gmail.com>
Sent: Thursday, 19 June 2025 12:25
To: core-libs-dev at openjdk.org <core-libs-dev at openjdk.org>
Subject: Gatherer JavaDoc
Hi, I have trio of minor questions about the Gatherer JavaDoc at https://download.java.net/java/early_access/jdk25/docs/api/java.base/java/util/stream/Gatherer.html
1. "Gatherers whose integrator is an instance of 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*."
The way it is worded, I get the impression that a greedy integrator could simply return false (or to save a letter, true), because, not inspected. But I am confused. It was my impression that any integrator, greedy or not, should return false if downstream.push returns false. Why would the implementation not want to know? (The current implementation does inspect the return value.)
2. "Gatherers whose finisher is defaultFinisher() are considered to not have an end-of-stream hook *and invoking their finisher is optional.*"
I don't get the significance of the "and" part. Why would anyone care if defaultFinisher is invoked? It's a no-op.
3. What is the use case for
static <T,R> Gatherer<T,Void,R>
of(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, Gatherer.Downstream<? super R>> finisher)
If there is no state, what can the finisher do?
Thanks,
Cay
--
Cay S. Horstmann | https://horstmann.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250619/921d0d21/attachment-0001.htm>
More information about the core-libs-dev
mailing list