Что должен реализовать класс в Java, чтобы его объекты можно было использовать в цикле for-each?

«Что должен реализовать класс в Java, чтобы его объекты можно было использовать в цикле for-each?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Чтобы объекты класса можно было использовать в цикле for-each, класс должен реализовать интерфейс Iterable<T>.

Требования:

  1. Реализовать единственный метод Iterable<T>.iterator().
  2. Метод iterator() должен возвращать объект, реализующий интерфейс Iterator<T>.
  3. Iterator<T> должен предоставлять реализации методов hasNext() (проверка наличия следующего элемента) и next() (получение следующего элемента).

Пример реализации:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class SimpleCollection<T> implements Iterable<T> {
    private final T[] elements;

    public SimpleCollection(T[] elements) {
        this.elements = elements.clone();
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            private int currentIndex = 0;

            @Override
            public boolean hasNext() {
                return currentIndex < elements.length;
            }

            @Override
            public T next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                return elements[currentIndex++];
            }
        };
    }

    // Использование в for-each
    public static void main(String[] args) {
        SimpleCollection<String> collection = new SimpleCollection<>(new String[]{"A", "B", "C"});
        for (String item : collection) { // Цикл for-each работает!
            System.out.println(item);
        }
    }
}

Почему Iterable, а не Iterator? Интерфейс Iterable декларирует, что класс может предоставить итератор, что позволяет одному классу иметь несколько независимых итераторов и является более абстрактным и гибким подходом.