Thanks for sharing your experience, David!

On 2025-11-17 15:08, David Alayachew wrote:
Hello @core-libs-dev <mailto:[email protected]>,

This is a follow up of one of my previous experience reports, a little over a year ago.

https://mail.openjdk.org/pipermail/core-libs-dev/2024-August/127293.html

Just wanted to report more of my positive experiences with Gatherers, specifically with a custom Gatherer that @Viktor Klang <mailto:[email protected]> made for me called windowBy. Here is the implementation below.

<TR> Gatherer<TR, ?, List<TR>> windowBy(Predicate<TR> includeInCurrentWindow) {
    class State {
        ArrayList<TR> window;

        boolean integrate(TR element, Gatherer.Downstream<? super List<TR>> downstream) {
            if (window != null && !includeInCurrentWindow.test(element)) {
                var result = Collections.unmodifiableList(window);
                window = null;
                if (!downstream.push(result))
                    return false;
            }

            if (window == null)
                window = new ArrayList<>();

            return window.add(element);
        }

        void finish(Gatherer.Downstream<? super List<TR>> downstream) {
            if (window != null) {
                var result = Collections.unmodifiableList(window);
                window = null;
                downstream.push(result);
            }
        }
    }
    return Gatherer.<TR, State, List<TR>>ofSequential(State::new, State::integrate, State::finish);
}

Clean and simple.

Anyways, as for my experience report, a found a brand new way to use this custom Gatherer -- event coalescing.

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.

Anyways, here are the 2 examples where it served me well.

 1. Network Request Coalescing.
     1. 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.
 2. Path-Finding Algorithm -- Clustering
     1. 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.

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!

Thank you all for your time and consideration!
David Alayachew

--
Cheers,
√


Viktor Klang
Software Architect, Java Platform Group
Oracle

Reply via email to