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.
Leave a Reply