Possible Duplicate:
Why is Java's Iterator not an Iterable?Idiomatic way to use for-each loop given an iterator?
Can we use for-each loop for iterating the objects of Iterator type?
The foreach loop are as far as I know syntax sugar added in Java 5. So
Iterable<O> iterable;
for(O o : iterable) {
// Do something
}
will essentially produce the same bytecode as
Iterable<O> iterable;
for(Iterator<O> iter = iterable.iterator(); iter.hasNext(); /* NOOP */) {
O o = iter.next();
// Do something
}
However, if I do not have an iterable in the first place, but only an iterator (say, because a class offers two different iterators), I cannot use the syntax sugar foreach loop. Obviously I can still do the plain old style iteration. However, I'd actually like to do:
Iterator<O> iter;
for(O o : iter /* Iterator<O>, not Iterable<O>! */) {
// Do something
}
And of course I can do a fake Iterable
:
class Adapter<O> implements Iterable<O> {
Iterator<O> iter;
public Adapter(Iterator<O> iter) {
this.iter = iter;
}
@Override
public Iterator<O> iterator() {
return iter;
}
}
(Which in fact is an ugly abuse of the Iterable API, as it can only be iterated once!)
If it were designed around Iterator
instead of iterable, one could do a number of interesting things:
for(O o : iterable.iterator()) {} // Iterate over Iterable and Collections
for(O o : list.backwardsIterator()) {} // Or backwards
Iterator<O> iter;
for(O o : iter) {
if (o.something()) { iter.remove(); }
if (o.something()) { break; }
}
for(O : iter) { } // Do something with the remaining elements only.
Does anyone know why the language was designed this way? To avoid ambiguity if a class would implement both Iterator
and Iterable
? To avoid programmer errors that assume that "for(O o : iter)" will process all elements twice (and forget to get a fresh iterator)? Or is there some other reason for this?
Or is there some language trick I just do not know?