<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Cay!</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks for the questions, see my responses below:</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
>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*."<br>
<br>
>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.)</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
No, it doesn't say that it <b>won't</b> be inspected, it says that it doesn't <b>
need to</b>. So if a user returns <b>false</b> from a greedy integrator's integrate-method, they can't be surprised if that signal isn't acted upon.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
The "evaluator" which operates on the Gatherer instance then has more freedom as to how it is implemented when it sees Greedy Integrators.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
>2. "Gatherers whose finisher is defaultFinisher() are considered to not have an >end-of-stream hook *and invoking their finisher is optional.*"<br>
<br>
>I don't get the significance of the "and" part. Why would anyone care if >defaultFinisher is invoked? It's a no-op.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
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:
<a href="https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherer.java#L250" id="LPlnk853899">
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Gatherer.java#L250</a></div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
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.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
For implementors of things which evaluate Gatherers: they can now avoid the overhead of invoking no-op finishers (which tend to be fairly common).</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
>3. What is the use case for<br>
<br>
>static <T,R> Gatherer<T,Void,R><br>
>of(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, >Gatherer.Downstream<? super R>> finisher)<br>
<br>
>If there is no state, what can the finisher do?</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Inject known data at the end of a stream, for instance:</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="line-height: normal; margin: 0px; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
jshell> Gatherer<String, Void, String> <b>s</b> = Gatherer.of((<u>_</u>, <b>s</b>,
<b>d</b>) -> d.push(s), (<u>_</u>, <b>d</b>) -> d.push("EOF"))</div>
<div class="elementToProof" style="line-height: normal; margin: 0px; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
s ==> GathererImpl[initializer=DEFAULT, integrator=$Lam ... 0000007e000cf838@5f3a4b84]</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="line-height: normal; margin: 0px; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
jshell> Stream.of("foo", "bar", "baz").gather(s).toList()</div>
<div class="elementToProof" style="line-height: normal; margin: 0px; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
$2 ==> [foo, bar, baz, EOF]</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="Signature" class="elementToProof">
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Cheers,<br>
–</div>
<div class="elementToProof" style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b><br>
</b></div>
<div class="elementToProof" style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<b>Viktor Klang</b></div>
<div class="elementToProof" style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="appendonsend"></div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<hr style="display: inline-block; width: 98%;">
<div id="divRplyFwdMsg">
<div style="direction: ltr; font-family: Calibri, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<b>From:</b> core-libs-dev <core-libs-dev-retn@openjdk.org> on behalf of Cay Horstmann <cay.horstmann@gmail.com><br>
<b>Sent:</b> Thursday, 19 June 2025 12:25<br>
<b>To:</b> core-libs-dev@openjdk.org <core-libs-dev@openjdk.org><br>
<b>Subject:</b> Gatherer JavaDoc</div>
<div style="direction: ltr;"> </div>
</div>
<div class="elementToProof" style="font-size: 11pt;">Hi, I have trio of minor questions about the Gatherer JavaDoc at
<a href="https://download.java.net/java/early_access/jdk25/docs/api/java.base/java/util/stream/Gatherer.html" id="OWAbe8bc572-8714-1fcb-d5e0-72e9d383b31c" class="OWAAutoLink" data-auth="NotApplicable">
https://download.java.net/java/early_access/jdk25/docs/api/java.base/java/util/stream/Gatherer.html</a><br>
<br>
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*."<br>
<br>
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.)<br>
<br>
2. "Gatherers whose finisher is defaultFinisher() are considered to not have an end-of-stream hook *and invoking their finisher is optional.*"<br>
<br>
I don't get the significance of the "and" part. Why would anyone care if defaultFinisher is invoked? It's a no-op.<br>
<br>
3. What is the use case for<br>
<br>
static <T,R> Gatherer<T,Void,R><br>
of(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, Gatherer.Downstream<? super R>> finisher)<br>
<br>
If there is no state, what can the finisher do?<br>
<br>
Thanks,<br>
<br>
Cay<br>
<br>
--<br>
<br>
Cay S. Horstmann | <a href="https://horstmann.com" id="OWAdbec931e-baba-1763-4258-598ea3cf0f55" class="OWAAutoLink" data-auth="NotApplicable">
https://horstmann.com</a><br>
<br>
</div>
</body>
</html>