Java: Iterators are not Iterable

This is something I stumbled across multiple times now in Java: Iterators are not Iterable. Java 1.5 introduced the foreach statement, which allows easy iteration over collections like this:

for (MyClass item: myCollection) {
    doStuffWithItem(item);
}

For this to work class MyClass must implement the Iterable interface. This interface defines just one method that returns an Iterator:

    Iterator<T> iterator();

This works fine in many cases. But now suppose we have a class that can be iterated in multiple ways. For example a Tree class that can be iterated breadth first or depth first. I would define two methods and use them like this:

class Tree {
    Iterator<Node> depthFirstIterator();
    Iterator<Node> breadthFirstIterator();
}

// ...
    for (Node node: myTree.depthFirstIterator()) {
    }

This won’t work in Java. Iterators do not extend the Iterable interface, like they in other languages. For example in Python an iterator will return itself when its iterator() equivalent is called. Instead in Java I have to return an object that itself implements the Iterable interface like this:

class IterableIterator<T> implements Iterable<T> {
    private Iterator<T> iter;

    public IterableIterator(Iterator<T> iter) {
        this.iter = iter;
    }

    public Iterator<T> iterator() {
        return iter;
    }
}

class Tree {
    IterableIterator<Node> depthFirstIterator();
    IterableIterator<Node> breadthFirstIterator();
}

Not only is this boilerplate code for no gain, a generic class like the IterableIterator above is not included in Java’s standard library.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *