Thank you both for your replies!

And thanks for the Gatherer example Viktor.

It sounds like, from your email, that you want to see just how useful this
method would be to add before we can justify adding it to Gatherers.

Fair enough. I have spent a couple of days using this custom Gatherer you
made for me, and I will post a new email thread either tomorrow or the day
after that shows my experience with it. My hope is that I can convince you
that this function absolutely is worth adding.

Thank you for your time and help!
David Alayachew

On Wed, Jan 10, 2024 at 2:29 PM Viktor Klang <viktor.kl...@oracle.com>
wrote:

> >1/ Is there a reason why the integrator is not declared greedy (I'm still
> not sure to what exactly Greedy means in the context of gatherers) ?
>
> No, that was just a (benign) omission from typing the solution as I was
> typing the email 🙂
>
> >2/ Is there a reason to write the code in a OOP way like you have done
> instead of only having fields in State and specify the behaviors using
> lambdas (because with lambdas will you get inference)
>
> Great question!
> I chose to do that since I wanted to A) allocate the backing list
> on-demand, and also B) not allocate a new ArrayList for the downstream
> windows and retain the (cleared) old one (since its size could become
> needlessly large).
>
>
> As a side-note, I tend to prototype using lambdas and then refactor
> as/when needed to either embed logic in the state or even migrate into a
> full-on implementation of the Gatherer interface (for instance if I want to
> override composition).
>
> Cheers,
> √
>
>
> *Viktor Klang*
> Software Architect, Java Platform Group
> Oracle
>
>
> ------------------------------
> *From:* Remi Forax <fo...@univ-mlv.fr>
> *Sent:* Wednesday, 10 January 2024 19:16
> *To:* Viktor Klang <viktor.kl...@oracle.com>
> *Cc:* David Alayachew <davidalayac...@gmail.com>; core-libs-dev <
> core-libs-dev@openjdk.org>
> *Subject:* [External] : Re: Gatherers -- conditionalWindowFixed?
>
>
>
> ------------------------------
>
> *From: *"Viktor Klang" <viktor.kl...@oracle.com>
> *To: *"David Alayachew" <davidalayac...@gmail.com>, "core-libs-dev" <
> core-libs-dev@openjdk.org>
> *Sent: *Wednesday, January 10, 2024 2:33:45 PM
> *Subject: *Re: Gatherers -- conditionalWindowFixed?
>
> Hi David!
>
> Apologies for the late reply, there's been lots of catching up to do after
> the holidays.
>
> >I'm really excited for what this will enable for us.
>
> I'm really glad to hear that \uD83D\uDE42
>
> >It is very much appreciated.
>
> \uD83D\uDC4D
>
> > Could we add one more method for a conditionalWindowFixed? We would need
> to pass in some Predicate<T>. If the predicate returns true, create a list
> (if it does not already exist) then add the element to it. If the predicate
> returns false while the list is empty, then just move along to the next.
> Else if the predicate returns false while the list is non empty, pass the
> list down into the stream. So, you end up with Stream<T> ----->
> Stream<List<T>>.
>
> What ends up under Gatherers.* does require careful triaging, ideally by
> first seeing user-created implementations being heavily used/useful, then
> potential candidate for Gatherers.*, and then at the end it might end up in
> Stream as a dedicated method.
>
> By virtue of the Gatherers API, it seems pretty straight-forward for you
> to implement what you describe, and personally I'd probably call it
> something like *windowBy*.
>
> Just typing this up as I write this reply, it could look something like
> this:
>
> <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);
> }
>
> jshell> Stream.of("header", "value1", "value2", "header", "header", "value
> 3", "value 4",
> null).gather(windowBy(Predicate.not("header"::equals))).toList()
> $1 ==> [[header, value1, value2], [header], [header, value 3, value 4,
> null]]
>
>
> Hello,
> I've two questions,
> 1/ Is there a reason why the integrator is not declared greedy (I'm still
> not sure to what exactly Greedy means in the context of gatherers) ?
> 2/ Is there a reason to write the code in a OOP way like you have done
> instead of only having fields in State and specify the behaviors using
> lambdas (because with lambdas will you get inference)
>
> <T> Gatherer<T, ?, List<T>> windowBy(Predicate<? super T>
> includeInCurrentWindow) {
>   class State {
>     ArrayList<T> window;
>   }
>   return Gatherer.ofSequential(
>       State::new,
>       (state, element, downstream) -> {
>        ...
>       },
>       (state, downstream) -> {
>         ...
>       });
> }
>
>
> Cheers,
> √
>
>
> regards,
> Rémi
>
>
>
> *Viktor Klang*
> Software Architect, Java Platform Group
> Oracle
> ------------------------------
> *From:* core-libs-dev <core-libs-dev-r...@openjdk.org> on behalf of David
> Alayachew <davidalayac...@gmail.com>
> *Sent:* Wednesday, 10 January 2024 07:05
> *To:* core-libs-dev@openjdk.org <core-libs-dev@openjdk.org>
> *Subject:* Gatherers -- conditionalWindowFixed?
>
> Hello Core Libs Dev Team,
>
> I have been reading through JEP 461 (https://openjdk.org/jeps/461) about
> Gatherers, and I'm really excited for what this will enable for us.
>
> By far, the most important functionality that this API facilitates is the
> ability to create windows. Anytime I needed a window, I was basically
> forced to use a for loop. Now, the 2 most common window cases are being
> handed to us for free. It is very much appreciated.
>
> Could we add one more method for a conditionalWindowFixed? We would need
> to pass in some Predicate<T>. If the predicate returns true, create a list
> (if it does not already exist) then add the element to it. If the predicate
> returns false while the list is empty, then just move along to the next.
> Else if the predicate returns false while the list is non empty, pass the
> list down into the stream. So, you end up with Stream<T> ----->
> Stream<List<T>>.
>
> The reason I think this is worth adding is because it facilitates a really
> common use case. We may not want all windows to be the same size.
>
> Is this something worth adding to the Gatherers API?
>
> Thank you for your time and help!
> David Alayachew
>
>

Reply via email to