for (String item : arrayList)
if (item.length() > 2)
arrayList.remove(item);
Подвох в том, что итератор
ArrayList
, который используется в таком варианте цикла for
, является fail-fast, то есть не поддерживает итерацию с параллельной модификацией. А параллельная модификация случается даже в одном потоке, что демонстрирует этот пример. Следующий шаг итератора после удаления элемента выбросит ConcurrentModificationException
.Не исключение, но неожиданный результат получится если пользоваться не итератором, а обычным циклом
for
– при каждом удалении нумерация элементов будет сдвигаться.Единственный способ удалить элемент из коллекции при обходе, не получив при этом
ConcurrentModificationException
или неопределенное поведение – удалить с помощью remove()
того же инстанса итератора. Вариант ListIterator поможет, если в теле цикла требуется и работа с индексами.Некоторые коллекции, такие как
CopyOnWriteArrayList
и ConcurrentHashMap
адаптированные под многопоточную среду и имеют fail-safe итераторы.