Doug Lea dl at cs.oswego.edu
Tue Feb 12 04:52:23 PST 2013

On 02/11/13 10:34, Remi Forax wrote:
> There is another point,
> the specification should be relatex to allow tryAdvance to not always call the
> consumer taken as parameter.

These are all the same issue in disguise (including the one
you mentioned that I didn't get :-)

The question is: Can you design Spliterators and/or
related leaf-computation-level support such that none
of the "basic" Stream ops require use of a lambda / inner class
that needs a mutable variable?

I took this path in ConcurrentHashMap
resulting in 4 "basic" methods
(plus 3 more for primitives). I think it is the right solution
for CHM, but it cannot apply to Streams (CHM can rely on
nullness, and imposes requirement that users pre-fuse multiple
map and map-reduce ops, etc.)

And if you explore what it would take to do this for the
Stream API, it gets quickly out of hand -- at least
a dozen or so operations that every Collection, Map, or
other Stream/Spliterator source author would have to write.
Which led to the present solution of only requiring
forEach, trySplit, and tryAdvance.


> If by example, I want to implements a Spliterator that filter the elements,
> this implementation should be legal:
> class FilterSpliterator implements Spliterator {
>    private final Spliterator spliterator;
>    private final Predicate predicate;
>    public FilterSpliterator(Spliterator spliterator, Predicate predicate) {
>       ....
>    }
>    public void tryAdvance(Consumer consumer) {
>       spliterator.tryAdvance(element -> {
>          if (predicate.test(element)) {
>            consumer.accept(element);
>          }
>       });
>    }
> }
> otherwise, you have to use a while loop around spliterator.tryAdvance but
> because there is  no way to transmit the information that the element is
> accepted or not
> (see my previous mail), you can not use a lambda here and you have to rely on an
> inner class.
> cheers,
> Rémi

More information about the lambda-libs-spec-observers mailing list