Вопрос с собеседования · Java

Для чего служит интерфейс Iterator?

JuniorКоллекции
Ещё спрашивают так:
  • Что такое ConcurrentModificationException?
  • Как удалить элемент из коллекции во время обхода?
  • Как работает цикл for-each?
Коротко

Iterator даёт единый способ обойти коллекцию, не раскрывая её устройства: hasNext() и next().

  • for-each — синтаксический сахар над итератором
  • Удалять во время обхода — только iterator.remove() или removeIf

А ещё Изменение коллекции напрямую при обходе → ConcurrentModificationException (fail-fast)

Подробно

Интерфейс Iterator описывает последовательный обход: hasNext() — есть ли следующий элемент, next() — получить его, remove() — удалить последний полученный. Клиенту не важно, что внутри — массив, дерево или связный список.

Цикл for (T x : collection) компилятор разворачивает в получение итератора и вызовы hasNext() / next(). Работает для всего, что реализует Iterable.

Fail-fast. Итераторы стандартных коллекций (ArrayList, HashMap) запоминают счётчик изменений коллекции. Если коллекцию изменить мимо итератора — например, list.remove(x) внутри for-each — при следующем next() будет ConcurrentModificationException. Это защита от непредсказуемого результата, а не гарантия при многопоточности.

Как удалять правильно:

  • iterator.remove() в явном цикле с итератором;
  • collection.removeIf(predicate) — короче и понятнее;
  • собрать новую коллекцию через Stream.

Конкурентные коллекции (ConcurrentHashMap, CopyOnWriteArrayList) используют слабо согласованные итераторы, которые исключение не бросают.

Пример

List<Integer> nums = new ArrayList<>(List.of(1, 2, 3, 4));
// for (Integer n : nums) if (n % 2 == 0) nums.remove(n); // ConcurrentModificationException
nums.removeIf(n -> n % 2 == 0);                            // [1, 3]

Что хотят услышать

  • Назначение итератора: единый обход без раскрытия устройства.
  • Связь с for-each.
  • ConcurrentModificationException и fail-fast.
  • Правильные способы удаления при обходе.

Частые ошибки

  • Удалять элементы через саму коллекцию внутри цикла for-each.
  • Считать, что обход как-то защищает коллекцию от параллельных изменений.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Сортирует элементы коллекции при обходе
  • ✗Делает коллекцию потокобезопасной на всё время обхода
  • ✓Единый обход коллекции без знания её устройства
  • ✗Копирует коллекцию перед обходом

Что спросят дальше

  • Что произойдёт при изменении коллекции во время обхода?
  • Как корректно удалить элементы по условию?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования