Что такое Fail Fast итератор в Java?

«Что такое Fail Fast итератор в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Fail Fast итератор — это поведение по умолчанию для большинства стандартных коллекций Java (например, ArrayList, HashMap, HashSet), при котором любое структурное изменение коллекции (кроме изменения через методы самого итератора) во время итерации приводит к немедленному выбросу ConcurrentModificationException. Это механизм "быстрого отказа", предназначенный для выявления ошибок на этапе разработки.

Принцип работы: Коллекция содержит внутренний счетчик модификаций (modCount). При каждой структурной модификации (добавление, удаление) этот счетчик увеличивается. Итератор при создании запоминает ожидаемое значение счетчика (expectedModCount). На каждой итерации (next(), remove()) проверяется равенство modCount == expectedModCount. Если они не равны — бросается исключение.

Пример, вызывающий исключение:

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
for (String s : list) { // Используется итератор 'for-each'
    if (s.equals("b")) {
        list.remove(s); // Структурное изменение коллекции НЕ через итератор!
        // Выбросит ConcurrentModificationException
    }
}

Как правильно изменить коллекцию во время итерации?

  1. Использовать метод remove() самого итератора:
    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
        String s = iterator.next();
        if (s.equals("b")) {
            iterator.remove(); // Безопасно! Корректно обновляет expectedModCount
        }
    }
  2. Собрать элементы для удаления и выполнить операцию после цикла.
  3. Использовать потоковые API (Java 8+): list.removeIf(s -> s.equals("b"));

Когда возникает исключение?

  • Прямое изменение коллекции (добавление/удаление) во время итерации.
  • Итерация по одной коллекции из нескольких потоков без синхронизации.

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