Iterator.forEachRemaining and Iterator.remove

Paul Sandoz paul.sandoz at oracle.com
Tue Oct 25 21:30:24 UTC 2016


Hi Martin,

Hmm…

The intent of ArrayList/Vector/LinkedList implementations is clear, leave the iterator in the same state as a last successful next call.

I believe ArrayDeque’s iterator (in repo, unsure about your updates) has different behaviour e.g.

  ad.next();
  ad.forEachRemaining(…);
  ad.remove(); // which element is removed?


We also don’t say anything about the behaviour if remove is called by the consumer function. This is potentially more problematic since we often optimize for the bulk operation and don’t update state within the loop.

I am inclined to say the behaviour in both cases is undefined, which we could mention in the documentation.

Paul.

> On 24 Oct 2016, at 12:32, Martin Buchholz <martinrb at google.com> wrote:
> 
> It doesn't make a lot of sense for users to call Iterator.remove after calling Iterator.forEachRemaining.
> 
> The default implementation has no choice but to do
> 
>         while (hasNext())
>             action.accept(next());
> 
> upon which remove() removes the last element.  What should overriding implementations do?  Emulate the default implementation's behavior or throw IllegalStateException, or even remove the element returned by the last actual call to next?  The spec is (perhaps intentionally) unclear on this point.  I'm thinking we emulate the default implementation's behavior, because common collections like ArrayList work this way, and some users may be depending on it, perhaps unwisely.



More information about the core-libs-dev mailing list