Это может немного сбивать с толку, так как Javado c сначала заявляет, что
Итераторы, возвращаемые всеми "методами представления коллекции" этого класса (values()
, keySet()
, entrySet()
) не подвержены сбоям: если карта в любой момент после создания итератора структурно изменяется, любым способом, кроме как через собственный метод удаления итератора, итератор выдаст ConcurrentModificationException
.
Примечание. что отказоустойчивое поведение итератора не может быть гарантировано
Но оно также заявляет в HashMap.entrySet ()
Возвращает представление Set из отображений, содержащихся в этой карте. Набор опирается на карту, поэтому изменения в карте отражаются в наборе, и наоборот. Если карта изменяется во время выполнения итерации по набору (кроме как через собственную операцию удаления итератора или через операцию setValue для записи карты, возвращаемой итератором) результаты итерации не определены .
сейчас не определено включает включает бросание ConcurrentModificationException
, но есть много случаев , где оно не выбрасывается, потому что, как видно в начале, поведение при сбое не может быть гарантировано .
Так что, если вы выполняете итерации keySet()
, values()
или entrySet()
и Вы модифицируете Map
структурно, то есть remove()
или put
новым ключом (не заменяя значение существующего ключа), вы можете получить: ConcurrentModificationException
или странные вещи, происходящие с итерацией, например как пропуск элементов или столкновение с элементом дважды.