Making a Set Iterable
We said earlier that the enhanced for loop is shorthand. The compiler expands it into method calls. The expanded loop calls a method named iterator() on the data structure. That call returns a small helper object, and the loop uses it to get the elements one at a time until there are none left. For now, all we need to know is that the data structure must have an iterator() method.
Java has a standard interface for this requirement, Iterable<T>:
public interface Iterable<T> {
Iterator<T> iterator();
}
A type works in an enhanced for loop only if it implements Iterable<T>. Arrays are the one exception. The language handles them as a special case.
So to use our set in an enhanced for loop, we have the Set interface extend Iterable<T>:
public interface Set<T> extends Iterable<T> {
boolean add(T item);
boolean remove(T item);
boolean contains(T item);
int size();
}
Here one interface extends another. That means its contract includes all the methods of the other interface. So Set<T> now has the iterator() method of Iterable<T> in addition to its own four, and every Set is also an Iterable. With that, the compiler accepts a Set in an enhanced for loop.
But the loop does not work yet. Every class that implements Set must now have its own iterator() method. That includes ArraySet and LinkedSet. Neither of them has one yet, so neither will compile until we write it. And that method has to return an Iterator<T>, the helper object that actually produces the elements.