Закрытие java.util. Итератор

Я реализовал пользовательский 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. Моя проблема состоит в том, когда итерация цикла повреждается перед последним повторением, поскольку это показывают в моем примере.

32
задан Josh Crozier 11 December 2015 в 00:29
поделиться

3 ответа

Проблема заключается в условии в конце .Часто мы перебираем всю коллекцию или набор данных, поэтому на данный момент мы в конце , данных для чтения не осталось.

Но если мы установим прерывание цикла до того, как мы достигнем Конца данных, итератор не подошел бы к концу и не закрывался бы.

Выходом может быть кэширование содержимого источника данных в итераторе во время построения и закрытие ресурса. Таким образом, итератор будет работать не с открытым ресурсом, а с кешированными данными.

9
ответ дан 27 November 2019 в 20:41
поделиться

Вы можете закрыть его в финализаторе , но он не даст вам желаемого поведения. Ваш финализатор вызывается только тогда, когда сборщик мусора хочет очистить ваш объект, поэтому ваш ресурс может оставаться открытым. Хуже того, если кто-то держится за ваш итератор, он никогда не закроется.

Существует возможность закрытия потока при первом вызове hasNext (), который возвращает false. Это все еще не гарантировано, поскольку кто-то может повторить только первый элемент и никогда больше не возиться с ним.

На самом деле, я думаю, вам придется управлять этим самостоятельно, когда имеете дело с внешней библиотекой. Вы собираетесь сделать эти вызовы методов, которые используют итерацию, так почему бы не закрыть ее самостоятельно, когда закончите? Управление ресурсами - это не то, что вы можете просто навязать внешней библиотеке, которая ничего не знает лучше.

7
ответ дан 27 November 2019 в 20:41
поделиться

В вашей реализации вы могли бы закрыть его самостоятельно, если итератор исчерпан.

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.

14
ответ дан 27 November 2019 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: