Я реализовал пользовательский java.util. Итератор с помощью ресурса, который должен быть выпущен в конце с помощью a close()
метод. Тот ресурс мог быть java.sql. ResultSet, java.io. InputStream и т.д...
public interface CloseableIterator<T> extends Iterator<T>
{
public void close();
}
Некоторые внешние библиотеки с помощью этого итератора не могли бы знать, что он должен быть закрыт. например:
public boolean isEmpty(Iterable<T> myiterable)
{
return myiterable.iterator().hasNext();
}
В этом случае существует ли способ закрыть этот итератор?
Обновление: большое спасибо за текущие ответы. Я дам (+1) всем. Я действительно уже закрываю Итератор, когда hasNext () возвращает false. Моя проблема состоит в том, когда итерация цикла повреждается перед последним повторением, поскольку это показывают в моем примере.
Проблема заключается в условии в конце .Часто мы перебираем всю коллекцию или набор данных, поэтому на данный момент мы в конце , данных для чтения не осталось.
Но если мы установим прерывание цикла до того, как мы достигнем Конца данных, итератор не подошел бы к концу и не закрывался бы.
Выходом может быть кэширование содержимого источника данных в итераторе во время построения и закрытие ресурса. Таким образом, итератор будет работать не с открытым ресурсом, а с кешированными данными.
Вы можете закрыть его в финализаторе , но он не даст вам желаемого поведения. Ваш финализатор вызывается только тогда, когда сборщик мусора хочет очистить ваш объект, поэтому ваш ресурс может оставаться открытым. Хуже того, если кто-то держится за ваш итератор, он никогда не закроется.
Существует возможность закрытия потока при первом вызове hasNext (), который возвращает false. Это все еще не гарантировано, поскольку кто-то может повторить только первый элемент и никогда больше не возиться с ним.
На самом деле, я думаю, вам придется управлять этим самостоятельно, когда имеете дело с внешней библиотекой. Вы собираетесь сделать эти вызовы методов, которые используют итерацию, так почему бы не закрыть ее самостоятельно, когда закончите? Управление ресурсами - это не то, что вы можете просто навязать внешней библиотеке, которая ничего не знает лучше.
В вашей реализации вы могли бы закрыть его самостоятельно, если итератор исчерпан.
public boolean hasNext() {
....
if( !hasNext ) {
this.close();
}
return hasNext;
}
И ясный документ:
Этот итератор вызовет close(), когда hasNext() вернет false, если вам нужно утилизировать итератор до этого, убедитесь, что вы вызываете close your self
пример:
void testIt() {
Iterator i = DbIterator.connect("db.config.info.here");
try {
while( i.hasNext() {
process( i.next() );
}
} finally {
if( i != null ) {
i.close();
}
}
}
Btw, вы могли бы, пока вы там, реализовать Iterable и использовать расширенный цикл for.