RFR 8168745 Iterator.forEachRemaining vs. Iterator.remove

Martin Buchholz martinrb at google.com
Mon Nov 21 21:21:45 UTC 2016


On Mon, Nov 21, 2016 at 1:01 PM, Paul Sandoz <paul.sandoz at oracle.com> wrote:

>
> > There's the question of what to promise after a call to forEachRemaining
> (whether or not an action threw).  Perhaps a blanket
> > """Subsequent behavior of an iterator is unspecified after a call to
> this method."""
> >
>
> I think that is overly limiting, it’s exceptions and remove that are
> problematic. Assuming no exception it is fine to subsequently call next,
> hasNext and forEachRemaining, each has well defined behaviour (throws
> NoSuchElementException, false, no-op respectively).
>

In a concurrent world, it's not so clear.  A linked list based
implementation could report hasNext() == false when currentNode.next ==
null, but that might change before the next call to hasNext().  AFAIK, all
of our concrete implementations don't have this property - the iterator
being exhausted is a "sticky" property, in part because it's nice to the GC
to null out fields at the end.  One can imagine an iterator (or
spliterator) designed to work differently, e.g. tryAdvance would be a way
of "polling" the stream of elements to see whether any are available, and
would eventually visit all elements added.

Back in the real world, forEachRemaining is a particularly strong hint that
this iterator/spliterator should be forever exhausted.  Perhaps where that
matters (ArrayBlockingQueue) we could even add such a thing to the spec.
We discourage use of Iterators with ABQ, in part because in the past there
was no way to "close" an Iterator.  But now there is!


More information about the core-libs-dev mailing list