Iterable and Iterator

For things that are not arrays, a for-each loops are built on top of two interfaces: java.lang.Iterable and java.lang.Iterator.

The Iterator interface defines two methods: hasNext and next1. Iterators let you box up the logic of how to loop over something.

public interface Iterator<T> {
    // Will return true if there are more elements
    // false otherwise
    boolean hasNext();

    // Gets an element and advances the iterator forwards
    T next();
}

Iterable then just has one method which gives you an Iterator.

interface Iterable<T> {
    // Gives a "fresh" Iterator
    Iterator<T> iterator();
}

This is needed because Iterators are "one shot." It starts at the beginning of a collection and advances across every element each time next is called. In order to loop over something multiple times you need a fresh iterator each time.

A for-each loop over an Iterable object more or less translates to this style of while loop.2

for (String thing : iterable) {
    // ...
}

// is the same as

Iterator<String> iter = iterable.iterator();
while (iter.hasNext()) {
    String thing = iter.next();
    // ...
}
1

There is actually one more method: remove. Not all Iterators support it so we'll cover it whonce we've introduced more Iterable things.

2

I think this is important to know because otherwise it won't make sense when you run in to things you can loop over but don't have .get/[], `