Java File API

I don’t like Java’s File API. It’s main problem is that is mixes several responsibilities into one class. One responsibility is handling of “abstract” file and path names, i.e. operating system independent file names. The other responsibilities are all file system related: Querying file meta information (access rights, access times, file type), creating files, and listing directory contents. In my opinion these should be clearly separated.

I am also missing a constructor or construction method that creates a File instance from a list of path components like this:

  File f = new File("/", "path", "to", "file");

Maybe I should start a Java warts page, similar to my Python warts page …

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.