Возможный дубликат:
Почему Java Iterator не является итерабельным?Идиоматический способ использования для каждого цикла, заданного итератором?
Можно ли использовать цикл for для каждого итерации объектов типа Iterator?
Цикл foreach - это насколько я знаю, что в Java добавлен синтаксический сахар. Итак
Iterable<O> iterable;
for(O o : iterable) {
// Do something
}
будет по существу производить тот же байт-код, что и
Iterable<O> iterable;
for(Iterator<O> iter = iterable.iterator(); iter.hasNext(); /* NOOP */) {
O o = iter.next();
// Do something
}
Однако, если у меня нет итерации в первую очередь, а только итератора (скажем, потому что класс предлагает два разных итератора), я не могу использовать синтаксический цикл foreach. Очевидно, я все еще могу выполнить обычную старую итерацию стиля. Тем не менее, я бы действительно хотел:
Iterator<O> iter;
for(O o : iter /* Iterator<O>, not Iterable<O>! */) {
// Do something
}
И, конечно, я могу сделать подделку 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;
}
}
(что на самом деле является уродливым злоупотреблением API-интерфейсом Iterable, поскольку его можно только повторить один раз!)
Если он был создан вокруг Iterator
вместо iterable, можно было бы сделать несколько интересных вещей:
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.
Кто-нибудь знает, почему язык был разработан таким образом? Чтобы избежать двусмысленности, если класс будет реализовывать как Iterator
, так и Iterable
? Чтобы избежать ошибок программиста, предполагающих, что "for (O o: iter)" будет обрабатывать все элементы дважды (и забыть получить свежий итератор)? Или есть еще одна причина для этого?
Или есть какой-то трюк, который я просто не знаю?