Java – Should I return Iterable or Enumeration in Java

collectionsimmutabilityjava

In order to achieve better immutability, should my API return java.lang.Iterable<T> or java.util.Enumeration<E>? Since Iterable's iterator has a remove() method, one could say Enumeration is the right choice, but the javadoc says "New implementations should consider using Iterator in preference to Enumeration".

I'm aware about unmodifiable collections, but in that case we still end up with collections that expose add and remove methods.

Any other options in Java?

Best Answer

As Brian says (and your reference to the docs), Iterables are much more common and what programmers are used to. Thus, use Iterable - it also allows to use the "foreach" statement, which does not support Enumeration.

As the unmodifiable collections are part of the base JDK, I would say that add/remove methods in the collection, and remove methods in the iterator, are exposed is just how it is in Java. It is instead common to simply document the API sufficiently, and throw UnsupportedOperationException where the user violates the API.

I would suggest the implementation of Tulains. However, throw an UnsupportedOperationException in remove instead of doing nothing. This communicates the interface correctly: you return an unmodifiable collection. This is also the behaviour of standard JDK classes (for instance emptySet() and unmodifiableList() from the Collections class).

For completeness, the implementation (with sufficient rep, I would have just commented on Tulains answer):

/* This is unmodifiable */
public class MyList<T> implements Iterable<T> {

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            @Override
            public boolean hasNext() {
                return false; // TODO: to implement
            }

            @Override
            public T next() {
                return null; // TODO: to implement
            }

            @Override
            public void remove() {  
                throw new UnsupportedOperationException();
            }
        };
    }

}

Note that I also moved the Iterator to an inner class to separate the collection and its iterator. This is also how it is done, for instance, for the class Collections.UnmodifiableList.