All 15 Collections Framework questions
More in Collections Framework
Advertisement
Java › Collections Framework

What is the difference between the Iterable and Iterator interfaces, and how does the enhanced for-each loop rely on them?

Beginner

Answer

Iterable is implemented by any class that can produce an Iterator via its single iterator() method, making it eligible for use in a for-each loop; Iterator itself provides the actual traversal mechanism via hasNext() (checks if more elements remain) and next() (returns the next element, advancing position), plus an optional remove() -- the compiler desugars a for-each loop over an Iterable into the equivalent explicit while-loop calling hasNext()/next() internally, meaning any custom class implementing Iterable automatically gains for-each loop support.
public class Range implements Iterable<Integer> {
    private final int start, end;
    public Range(int start, int end) { this.start = start; this.end = end; }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<>() {
            int current = start;
            public boolean hasNext() { return current < end; }
            public Integer next() { return current++; }
        };
    }
}

for (int i : new Range(1, 5)) { System.out.println(i); }  // works because Range implements Iterable
Real-world example A custom linked data structure implements Iterable<T>, letting application code iterate over it naturally with a standard for-each loop rather than requiring callers to know about and use a custom, non-standard traversal method.

Common follow-ups: What does the for-each loop actually compile down to under the hood?;Why does Iterator not extend Iterable, and what would go wrong if it did?