← Назад к вопросам
Что должен имплементировать класс для использования его объектов в For Each
2.0 Middle🔥 141 комментариев
#Коллекции#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Класс должен имплементировать интерфейс Iterable
Для использования объекта в for-each loop (enhanced for statement) класс ОБЯЗАТЕЛЬНО должен реализовать интерфейс Iterable<T> или наследоваться от класса, который его реализует.
Структура Iterable
public interface Iterable<T> {
// Единственный метод
Iterator<T> iterator();
}
Класс должен реализовать метод iterator(), который возвращает объект Iterator<T>.
Iterator интерфейс
public interface Iterator<T> {
// Проверяет, есть ли следующий элемент
boolean hasNext();
// Возвращает следующий элемент
T next();
// Опционально: удаление текущего элемента
void remove();
}
Минимальная реализация
import java.util.Iterator;
public class SimpleList<T> implements Iterable<T> {
private Object[] items = new Object[10];
private int size = 0;
public void add(T item) {
items[size++] = item;
}
@Override
public Iterator<T> iterator() {
return new SimpleIterator();
}
// Приватный класс-итератор
private class SimpleIterator implements Iterator<T> {
private int index = 0;
@Override
public boolean hasNext() {
return index < size;
}
@Override
public T next() {
return (T) items[index++];
}
}
// Теперь можно использовать в for-each
public static void main(String[] args) {
SimpleList<String> list = new SimpleList<>();
list.add("Java");
list.add("Python");
list.add("C++");
for (String lang : list) { // ✅ Работает!
System.out.println(lang);
}
}
}
Полный пример с правильной реализацией
import java.util.Iterator;
import java.util.NoSuchElementException;
public class CustomList<T> implements Iterable<T> {
private Node<T> head;
private int size;
public void add(T value) {
if (head == null) {
head = new Node<>(value);
} else {
Node<T> current = head;
while (current.next != null) {
current = current.next;
}
current.next = new Node<>(value);
}
size++;
}
@Override
public Iterator<T> iterator() {
return new CustomIterator(head);
}
// Узел связного списка
private static class Node<T> {
T value;
Node<T> next;
Node(T value) {
this.value = value;
}
}
// Реализация Iterator
private class CustomIterator implements Iterator<T> {
private Node<T> current;
CustomIterator(Node<T> head) {
this.current = head;
}
@Override
public boolean hasNext() {
return current != null;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T value = current.value;
current = current.next;
return value;
}
@Override
public void remove() {
// Опционально: реализовать удаление
}
}
public static void main(String[] args) {
CustomList<Integer> numbers = new CustomList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
// Используем в for-each
for (Integer num : numbers) {
System.out.println(num);
}
}
}
Как устроен For-Each под капотом
// For-each:
for (String item : list) {
System.out.println(item);
}
// Компилируется в эквивалент:
for (Iterator<String> iterator = list.iterator();
iterator.hasNext(); ) {
String item = iterator.next();
System.out.println(item);
}
Итератор как отдельный класс
import java.util.Iterator;
public class MyCollection<T> implements Iterable<T> {
private T[] items;
private int size;
public MyCollection(int capacity) {
items = (T[]) new Object[capacity];
size = 0;
}
public void add(T item) {
items[size++] = item;
}
@Override
public Iterator<T> iterator() {
return new MyIterator(); // Возвращаем новый экземпляр
}
// Публичный внешний класс
public class MyIterator implements Iterator<T> {
private int index = 0;
@Override
public boolean hasNext() {
return index < size;
}
@Override
public T next() {
return items[index++];
}
}
}
Встроенные примеры в Java
Все встроенные коллекции реализуют Iterable:
// Все эти классы реализуют Iterable
List<String> list = new ArrayList<>();
Set<Integer> set = new HashSet<>();
Queue<String> queue = new LinkedList<>();
// Поэтому все работают с for-each
for (String s : list) { }
for (Integer i : set) { }
for (String s : queue) { }
Анонимный итератор
public class SimpleIterable<T> implements Iterable<T> {
private T[] items;
private int size;
public SimpleIterable(int capacity) {
items = (T[]) new Object[capacity];
}
public void add(T item) {
items[size++] = item;
}
@Override
public Iterator<T> iterator() {
// Анонимный класс
return new Iterator<T>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < size;
}
@Override
public T next() {
return items[index++];
}
};
}
}
Java 8+: Stream вместо Iterator
public class ModernCollection<T> implements Iterable<T> {
private java.util.List<T> items = new java.util.ArrayList<>();
public void add(T item) {
items.add(item);
}
@Override
public Iterator<T> iterator() {
return items.iterator(); // Делегируем ArrayList
}
// Используем в for-each
public static void main(String[] args) {
ModernCollection<String> collection = new ModernCollection<>();
collection.add("a");
collection.add("b");
// For-each
for (String s : collection) {
System.out.println(s);
}
}
}
Ошибка при отсутствии Iterable
public class NonIterable {
private int[] values = {1, 2, 3};
}
// Ошибка при попытке использовать for-each:
NonIterable ni = new NonIterable();
for (int v : ni) { // ❌ COMPILE ERROR!
// Cannot resolve symbol 'iterator'
}
Чек-лист для реализации Iterable
- Реализовать интерфейс
Iterable<T> - Переопределить метод
iterator()→Iterator<T> - Создать класс, реализующий
Iterator<T>(внутренний или отдельный) - Реализовать методы
hasNext()иnext() - Опционально: реализовать
remove() - Обработать
NoSuchElementExceptionкогда итератор закончился
Заключение
Для использования объекта в for-each:
- Класс должен реализовать Iterable<T>
- Метод
iterator()возвращает Iterator<T> - Iterator имплементирует hasNext() и next()
- For-each синтаксис сахар вокруг Iterator pattern
- Все встроенные коллекции (List, Set, Queue) уже реализуют это