Может ли пользовательский объект в Java быть использован в цикле for-each?

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

Ответ

Да, может, если объект реализует интерфейс Iterable<T>. Для этого необходимо переопределить метод iterator(), который должен возвращать корректный объект Iterator<T>.

Почему это работает: Цикл for-each (for (Type item : collection)) на уровне компилятора преобразуется в итерацию по Iterator, полученному вызовом метода iterator() у объекта, реализующего Iterable.

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

import java.util.*;

class MyCollection<T> implements Iterable<T> {
    private List<T> items = new ArrayList<>();

    public void add(T item) {
        items.add(item);
    }

    @Override
    public Iterator<T> iterator() {
        // Возвращаем итератор внутреннего списка
        return items.iterator();
    }
}

// Использование:
public class Main {
    public static void main(String[] args) {
        MyCollection<String> collection = new MyCollection<>();
        collection.add("A");
        collection.add("B");

        for (String s : collection) {
            System.out.println(s); // Выведет A, затем B
        }
    }
}

Ключевые требования:

  1. Класс должен реализовывать Iterable<T>.
  2. Метод iterator() должен возвращать объект, реализующий Iterator<T>.
  3. Возвращаемый итератор должен корректно реализовывать методы hasNext() и next().