<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Thanks for sharing your experience, David!</p>
<div class="moz-cite-prefix">On 2025-11-17 15:08, David Alayachew
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAA9v-_NMTq_v=-i=wFA=n7DMT7T02cwU_MwjnzgkdVj2ZZUUTA@mail.gmail.com">
<div dir="ltr">
<div class="gmail_default" style="font-family:monospace">Hello <a class="gmail_plusreply" id="plusReplyChip-0" href="mailto:core-libs-dev@openjdk.org" tabindex="-1" moz-do-not-send="true">@core-libs-dev</a>,</div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace">This is
a follow up of one of my previous experience reports, a little
over a year ago.</div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace"><a href="https://mail.openjdk.org/pipermail/core-libs-dev/2024-August/127293.html" moz-do-not-send="true" class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/core-libs-dev/2024-August/127293.html</a></div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace">Just
wanted to report more of my positive experiences with
Gatherers, specifically with a custom Gatherer that <a class="gmail_plusreply" id="plusReplyChip-1" href="mailto:viktor.klang@oracle.com" tabindex="-1" moz-do-not-send="true">@Viktor Klang</a> made for me called
windowBy. Here is the implementation below.</div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace"><TR>
Gatherer<TR, ?, List<TR>>
windowBy(Predicate<TR> includeInCurrentWindow) {<br>
class State {<br>
ArrayList<TR> window;<br>
<br>
boolean integrate(TR element, Gatherer.Downstream<?
super List<TR>> downstream) {<br>
if (window != null &&
!includeInCurrentWindow.test(element)) {<br>
var result =
Collections.unmodifiableList(window);<br>
window = null;<br>
if (!downstream.push(result))<br>
return false;<br>
}<br>
<br>
if (window == null)<br>
window = new ArrayList<>();<br>
<br>
return window.add(element);<br>
}<br>
<br>
void finish(Gatherer.Downstream<? super
List<TR>> downstream) {<br>
if (window != null) {<br>
var result =
Collections.unmodifiableList(window);<br>
window = null;<br>
downstream.push(result);<br>
}<br>
}<br>
}<br>
return Gatherer.<TR, State,
List<TR>>ofSequential(State::new, State::integrate,
State::finish);<br>
}</div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace">Clean
and simple.</div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace">Anyways,
as for my experience report, a found a brand new way to use
this custom Gatherer -- event coalescing.</div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace">Sometimes,
if consecutive events being streamed are of the same type,
then to reduce computation, you might be able to avoid doing
more work by grouping together the potential duplicates, then
handling them separately in a coalescing path. I'd much rather
solve that problem than a caching problem lol.</div>
<div class="gmail_default" style="font-family:monospace"><br>
</div>
<div class="gmail_default" style="font-family:monospace">Anyways,
here are the 2 examples where it served me well.</div>
<br>
<div class="gmail_default" style="font-family:monospace">
<ol>
<li>Network Request Coalescing.</li>
<ol>
<li>When checking the availability of certain networks, I
am now able to save some bandwidth by combining
multiple, consecutive requests within a certain time to
a certain network. And since I am definitely bandwidth
bound, that helps. Nothing I couldn't do before, but
keeping it within Streams allowed me to avoid ripping
out my old solution when it stopped being a good fit. I
wish I could share the code, but it's not my right to
share it.</li>
</ol>
<li>Path-Finding Algorithm -- Clustering</li>
<ol>
<li>This one is still a work in progress, so I may be
speaking prematurely here. But I was so impressed that
this is working thus far. Long story short, I am
building a path-finding algorithm where, if a set of
points are close enough together, then they can be
serviced as a group, and thus, lower the total weight of
servicing those nodes, as opposed to servicing them
individually. Again, not done yet, so I might be jumping
the gun, but it worked so well for me out of the box,
that I thought it was worth sharing.</li>
</ol>
</ol>
<div>Hopefully this bumps up windowBy on the triage list of
potential pre-built gatherers to add to the standard
library. And thanks again to Viktor and friends for putting
this Gatherers library together -- it's a great addition!</div>
<div><br>
</div>
<div>Thank you all for your time and consideration!</div>
<div>David Alayachew</div>
</div>
</div>
</blockquote>
<pre class="moz-signature" cols="72">--
Cheers,
√
Viktor Klang
Software Architect, Java Platform Group
Oracle</pre>
</body>
</html>