EnumeratedStream

David Alayachew davidalayachew at gmail.com
Sat Apr 20 21:55:16 UTC 2024


I am in full support of this idea. I do also appreciate the functionality
of using a BiFunction<INDEX, T, R> on the map method instead of a normal
Function<WithIndex<T>, R>.

As for the actual enumeration logic, my vote is that it should simply
enumerate as it arrives, with no context or care given to what came before
it. Consider the following examples.

final List<Integer> list = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

System.out.println(list.stream().enumerated().filter((idx, val) -> val % 2
== 0).toList());
//0:0, 2:2, 4:4, 6:6, 8:8

System.out.println(list.stream().filter(val -> val % 2 ==
0).enumerated().toList());
//0:0, 1:2, 2:4, 3:6, 4:8

Enumeration is applied as it arrives, and no sooner. That, I feel, will
keep the implementation simplest, and allow the streaming logic to make the
most sense. And I added helpful reinterpretations of filter() method (like
you did with map()), but I don't think either is necessary.

Of course, the big question looming over all of this is -- does this
feature carry its weight? You and I vote yes, but let's see what the
community says.

What do you all think? Is this feature worth it -- with or without some
changes?

On Sat, Apr 20, 2024 at 5:07 PM ІП-24 Олександр Ротань <
rotan.olexandr at gmail.com> wrote:

> My proposal regarding findIndex brought up a topic that, as I see, has
> been brought up here multiple times.
>
> My idea is to extend the existing stream interface in the new
> EnumeratedStream interface. Such an approach has a number of advantages.
>
> 1. Some methods will be able to explicitly specify that they require an
> enumerated stream.
>
> 2. This would allow us to use an enumerated stream just as the default
> value stream, if the index is redundant at a certain processing step.
>
> 3. This could help introduce a more user-friendly interface: instead of
> passing pairs of index and value, they could be passed as separate
> variables, which will make code more concise.
>
> Consider following example:
> List.of(1, 2, 3).stream()
>                 .enumerated()
>                 .map(idx, value -> idx % 2 == 0 ? value : -value);
>
> looks much better than
> List.of(1, 2, 3).stream()
>                 .enumerated()
>                 .map(pair -> pair.idx % 2 == 0 ? pair.value : -pair.value);
>
> However, I see some caveats with this approach, which relate to parallel
> streams:
> when a stream is backed by a collection, you might expect assigned indexes
> to represent order of iteration through collection, especially when talking
> about sequential collections. Assigning indexes in such streams could be a
> difficult task in a parallel environment. It should either assign index to
> a stream elements at the moment when stream becomes parallelized, which is
> also impossible if already parallelized stream is being enumerated, and
> also wont work for infinite streams, or make enumerated stream at least
> partially sequential by passing elements to processing in order they were
> passed to stream at the first place, which is also hard or maybe even
> impossible to achieve.
>
> Also, side note: methods that already accept 2 parameters might become
> kinda verbose, like reduce that will have to accept for params (idx1, val1,
> idx2, val2), but i think that is not a big deal
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240420/6a658889/attachment.htm>


More information about the core-libs-dev mailing list