Hi Henrik,
I recall there was a thread for EnumeratedStream 
(https://mail.openjdk.org/pipermail/core-libs-dev/2024-April/thread.html#121871)
 back in April; it calls for the same feature, to add a stage for indexing 
entries.
This approach of using a gatherer is simple; its disadvantage is that when 
there is a next stage in the stream, the indices become invalidated and cause 
confusions for users.  This is not a problem in the Rust/Python enumerate 
examples, as they do not intend to be fluent like Stream.

I had a toy project that explores the consumption of (index, element) pairs: 
https://github.com/liachmodded/IndexedStream/blob/main/src/main/java/com/github/liachmodded/indexedstream/IndexedGatherers.java
This simple example takes predicates and functions that take an (index, 
element) pair and return a boolean/a next element. In the same package, there 
is also an Indexed.java API, which allows you to create Collector/Gatherer for 
an indexed entry, and re-fit that Collector/Gatherer to be general purpose.
These are all aimed to avoid propagating no-longer-valid indices to the next 
stage of the stream operations; and they aren't exactly pretty.

Do you have any justifications for the addition of this particular gatherer, so 
it should be provided in the Java Class Libraries instead of a user library?

Regards,
Chen Liang
________________________________
From: core-libs-dev <core-libs-dev-r...@openjdk.org> on behalf of Henrik Wall 
<xehpuk....@gmail.com>
Sent: Thursday, December 5, 2024 10:48 AM
To: core-libs-dev@openjdk.org <core-libs-dev@openjdk.org>
Subject: JEP 473: Proposal for new built-in gatherer `indexed`

Hey folks,

Not having access to the index of an element of a stream is often a
reason to fall back to a traditional loop, at least for me. I'd love
to have `Gatherers.indexed()` that looks something like this:

public static <TR> Gatherer<TR, ?, Map.Entry<Integer, TR>> indexed() {
    return Gatherer.ofSequential(
            () -> new int[1],
            Gatherer.Integrator.ofGreedy((state, element, downstream) ->
                    downstream.push(Map.entry(state[0]++, element)))
    );
}

(Potentially with a custom pair class to avoid auto-boxing.)

In other popular languages like Python or Rust, this is also called `enumerate`.

Any chance to get that in a future release?

Regards,
Henrik

Reply via email to