Какой интерфейс в Java обеспечивает возможность обхода элементов коллекции (итерирования)?

Ответ

Базовый интерфейс — java.lang.Iterable<T>. Его реализация позволяет объекту быть целью for-each цикла.

Контракт интерфейса:

public interface Iterable<T> {
    Iterator<T> iterator(); // Должен возвращать итератор
    // default-методы forEach() и spliterator()...
}

Как это работает:

  1. Коллекции (например, List, Set) реализуют Iterable<T>.
  2. Метод iterator() возвращает объект, реализующий интерфейс Iterator<T> с методами hasNext(), next() и remove().

Пример использования итератора:

List<String> names = List.of("Alice", "Bob", "Charlie");
Iterator<String> it = names.iterator();
while (it.hasNext()) {
    String name = it.next();
    System.out.println(name);
    // it.remove(); // Опциональное удаление элемента (поддерживается не всеми коллекциями)
}

Пример for-each (требует Iterable):

// Цикл for-each неявно вызывает iterator()
for (String name : names) {
    System.out.println(name);
}

Важно: Сам Iterable не является коллекцией. Это более общий контракт для любых объектов, которые можно обойти (например, DirectoryStream).

Ответ 18+ 🔞

А, слушай, вот это тема — про этот ваш Iterable<T>. Представь себе, блядь, как будто ты подходишь к шкафу с полками. Сам шкаф — это не коллекция, это просто шкаф, ёпта. Но у него есть одна важная фича: он тебе может выдать обходчика, который будет методично, как зануда, смотреть каждую полку и тащить с неё вещи. Вот этот шкаф и есть Iterable. Он говорит: "На, мудила, вот тебе итератор, иди обходи".

Суть контракта, если по-простому:

public interface Iterable<T> {
    Iterator<T> iterator(); // Обязан выдать того самого обходчика
    // А ещё там есть forEach() и spliterator() по умолчанию, но это уже детали
}

Как это в жизни выглядит:

  1. Все твои любимые коллекции — List, Set — они все, сука, реализуют этот Iterable<T>. Как будто подписывают бумажку: "Да, мы обходимые, нате".
  2. Метод iterator() возвращает объект-итератор. А у того уже свои три кита: hasNext() ("ещё есть?"), next() ("давай следующее!") и remove() ("удаляю это гавно!" — но осторожно, не все это поддерживают).

Вот смотри, как это в коде выглядит, если делать вручную:

List<String> names = List.of("Алиса", "Боб", "Чарли");
Iterator<String> it = names.iterator(); // Получил обходчика
while (it.hasNext()) { // Пока есть что брать
    String name = it.next(); // Бери следующее
    System.out.println(name);
    // it.remove(); // Можешь воткнуть удаление, но это на твой страх и риск, ёпта
}

А теперь магия! Тот же самый for-each цикл, который все так любят — он под капотом делает ровно эту хуйню! Он неявно вызывает iterator() и работает с ним. То есть:

// Эта красота...
for (String name : names) {
    System.out.println(name);
}
// ...полностью эквивалентна тому ручному обходу сверху. Java сама всё делает.

И главное, что часто путают: Сам Iterable — это не коллекция, блядь! Это более общая, ёбушки-воробушки, идея. Любой объект, который можно "пробежать", может реализовать этот интерфейс. Например, поток из каталога файлов (DirectoryStream) — он тоже Iterable. Он как бы говорит: "Я не гарантирую, что у меня всё лежит в памяти, как в ArrayList, но обойти меня ты можешь". Вот и вся философия, в рот меня чих-пых.