Ответ
Базовый интерфейс — java.lang.Iterable<T>. Его реализация позволяет объекту быть целью for-each цикла.
Контракт интерфейса:
public interface Iterable<T> {
Iterator<T> iterator(); // Должен возвращать итератор
// default-методы forEach() и spliterator()...
}
Как это работает:
- Коллекции (например,
List,Set) реализуютIterable<T>. - Метод
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() по умолчанию, но это уже детали
}
Как это в жизни выглядит:
- Все твои любимые коллекции —
List,Set— они все, сука, реализуют этотIterable<T>. Как будто подписывают бумажку: "Да, мы обходимые, нате". - Метод
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, но обойти меня ты можешь". Вот и вся философия, в рот меня чих-пых.