javaresourcesiterator

Closing a java.util.Iterator


I've implemented a custom java.util.Iterator using a resource that should be released at the end using a close() method. That resource could be a java.sql.ResultSet, a java.io.InputStream etc...

public interface CloseableIterator<T> extends Iterator<T>
  {
  public void close();
  }

Some external libraries using this iterator might not know that it must be closed. e.g:

public boolean isEmpty(Iterable<T> myiterable)
 {
 return myiterable.iterator().hasNext();
 }

In that case, is there a way to close this iterator?

Update: many thanks for the current answers . I'll give a (+1) to everybody. I do already close the Iterator when hasNext() returns false. My problem is when the loop iterating breaks before the last iteration as it is shown in my example.


Solution

  • Create a custom iterator which implement the AutoCloseable interface

    public interface CloseableIterator<T> extends Iterator<T>, AutoCloseable {
    }
    

    And then use this iterator in a try with resource statement.

    try(CloseableIterator iterator = dao.findAll()) {
        while(iterator.hasNext()){
           process(iterator.next());
        }
    }
    

    This pattern will close the underlying resource whatever happens: - after the statement complete - and even if an exception is thrown

    Finally, clearly document how this iterator must be used.

    If you do not want to delegate the close calls, use a push strategy. eg. with java 8 lambda:

    dao.findAll(r -> process(r));