On 04/26/2013 03:06 PM, Remi Forax wrote:
On 04/26/2013 02:50 PM, Paul Sandoz wrote:
On Apr 26, 2013, at 2:06 PM, David Holmes <david.hol...@oracle.com>
wrote:
To avoid blocking the feature, I have filed
https://jbs.oracle.com/bugs/browse/JDK-8013150 to refine the
behavior of remove and other ListIterator methods after
forEachRemaining returns.
I think the fact that the last element can be removed should be
specified as unspecified,
because it's more an artefact of the default implementation than
something which part
of the semantics.
I was wondering about that too. What happens if an implementing
class decides later on to override the default implementation? If
the overriding implementation does not conform to the same
behaviour as the default it could break compatibility.
Plus one could change code from:
while(it.hasNext() { doSomething(it.next()); }
doSomethingAtEnd(it);
to
it.forEachRemaining(this::doSomething}
doSomethingAtEnd(it);
All implementations must obey the contract of the specification, and
no clients should assume any kind of behaviour beyond what that
contract says.
That said I've lost the context of this particular issue - what is
the problem here?
What is the state of the Iterator after a call to
Iterator.forEachRemaining e.g.:
void doSometingAtEnd(Iterator it) {
it.remove();
}
IMO overriding forEachRemaining implementations should place the
iterator in the same state as the default method implementation. We
just need to call this out more clearly in the docs.
I don't like the fact that the default implementation dictates the
semantics of forEachRemaining.
It's cleaner to separate the two and says that you can replace the
while loop by forEachRemaining
only if the iterator is not used after the while loop.
Basically, it means that the semantics of forEachRemaining is more
like the semantics of the enhanced for loop.
Another "interesting" usage:
Iterator<?> i = ...;
i.forEachRemaining(e -> {
...
if (...) {
i.forEachRemaining(dummy -> {}); // drain it
}
...
});
It seems that mixing external and internal iteration in the same object
is like a box of chocolates. For internal iteration, Iterable.forEach is
more suitable than Iterator.forEachRemaining unless the later is
specified to have the common state for both external and internal
iteration, which means that internal can not be more effective than
external.
Regards, Peter
Paul.
Rémi