← Назад к вопросам

Что такое итератор?

1.3 Junior🔥 191 комментариев
#Коллекции#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Итератор в Java

Итератор — это объект, который позволяет последовательно обходить элементы коллекции (List, Set, Queue и т.д.) без необходимости знать её внутреннюю структуру. Это реализация паттерна Iterator из GoF.

Интерфейс Iterator

public interface Iterator<E> {
    boolean hasNext();      // Есть ли ещё элементы?
    E next();              // Получить следующий элемент
    void remove();         // Удалить текущий элемент (опционально)
}

Основное назначение

Итератор позволяет:

  • Обходить элементы независимо от их хранения (массив, связный список, хеш-таблица)
  • Инкапсулировать логику обхода
  • Безопасно удалять элементы во время итерации
  • Работать с коллекциями единообразно

Использование итератора

1. Классический способ:

List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");

Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    System.out.println(fruit);
}

2. Enhanced for loop (синтаксический сахар):

Это работает, потому что List реализует Iterable.

for (String fruit : fruits) {
    System.out.println(fruit);
}
// Эквивалентно:
// Iterator<String> it = fruits.iterator();
// while (it.hasNext()) {
//     String fruit = it.next();
// }

3. Безопасное удаление во время итерации:

List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5));

// НЕПРАВИЛЬНО — выбросит ConcurrentModificationException
for (Integer num : numbers) {
    if (num % 2 == 0) {
        numbers.remove(num); // Ошибка!
    }
}

// ПРАВИЛЬНО — используем iterator.remove()
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
    Integer num = it.next();
    if (num % 2 == 0) {
        it.remove(); // Безопасное удаление
    }
}

System.out.println(numbers); // [1, 3, 5]

ListIterator

ListIterator расширяет Iterator с дополнительными возможностями для работы со списками:

public interface ListIterator<E> extends Iterator<E> {
    boolean hasPrevious();  // Есть ли предыдущий элемент?
    E previous();          // Получить предыдущий элемент
    int nextIndex();       // Индекс следующего элемента
    int previousIndex();   // Индекс предыдущего элемента
    void set(E e);         // Заменить текущий элемент
    void add(E e);         // Добавить элемент перед текущей позицией
}

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

List<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue"));
ListIterator<String> listIt = colors.listIterator();

// Перемещение туда и сюда
while (listIt.hasNext()) {
    System.out.println("Forward: " + listIt.next());
}

while (listIt.hasPrevious()) {
    System.out.println("Backward: " + listIt.previous());
}

// Добавление и замена
listIt = colors.listIterator();
listIt.next(); // Skip "Red"
listIt.set("Crimson"); // Replace "Green"
listIt.add("Yellow"); // Add before "Blue"

System.out.println(colors); // [Red, Crimson, Yellow, Blue]

Реализация собственного итератора

public class CustomList<E> implements Iterable<E> {
    private E[] elements;
    private int size = 0;
    
    @Override
    public Iterator<E> iterator() {
        return new CustomIterator();
    }
    
    private class CustomIterator implements Iterator<E> {
        private int index = 0;
        
        @Override
        public boolean hasNext() {
            return index < size;
        }
        
        @Override
        public E next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return elements[index++];
        }
        
        @Override
        public void remove() {
            // Логика удаления элемента
        }
    }
}

Ключевые различия: Iterator vs Stream

  • Iterator: Императивный стиль, состояние хранит позицию
  • Stream (Java 8+): Функциональный стиль, ленивые вычисления
// Iterator
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

// Stream
list.stream()
    .forEach(System.out::println);

Когда использовать

  • Итератор: Когда нужно контролировать процесс итерации (удалять, двигаться туда-сюда)
  • Enhanced for: Когда просто проходим по коллекции
  • Stream: Для функциональной обработки данных (map, filter, reduce)
Что такое итератор? | PrepBro