Начиная с Java 5, у нас есть новый тип java.lang.Iterable
, который можно использовать в циклах foreach как таковых:
for (Object element : iterable);
Контракт Iterable
не указывает, будет ли его iterator()
можно вызывать более одного раза перед удалением итерации. I.e., неясно, можно ли ожидать, что следующее будет работать для всех Iterables
:
for (Object element : iterable);
for (Object element : iterable);
Например, реализация Iterator
wrapping не может использоваться дважды:
public class OneShotIterable<T> implements Iterable<T> {
private final Iterator<T> it;
public OneShotIterable(Iterator<T> it) {
this.it = it;
}
@Override
public Iterator<T> iterator() {
return it;
}
}
Для большинства Iterables
это не имеет значения, поскольку они на самом деле являются ретро-установленными типами API коллекции, такими как List
, Set
, которые уже имеют четко определенные контракты для своих методов iterator()
.
Мой вопрос: Является ли реализация OneShotIterable
нарушением какого-либо контракта, который я пропускаю? Другими словами, будут ли пользователи Iterable
ожидать, что они будут повторно использоваться? Если да, существует ли "официальная" рекомендация экспертной группы Java 5, как бороться с таким "одним выстрелом" Iterables
(например, выбросить IllegalStateException
при втором вызове)?