Вы не можете изменить коллекцию во время итерации по ней - к сожалению, вы делаете это здесь с users
, и в результате получается ConcurrentModificationException От собственных javadocs ArrayList :
Итераторы, возвращаемые методами iterator
и listIterator
этого класса, fail-fast : если список структурно изменен в любое время после создания итератора, любым способом, кроме как через итератор собственные remove
или add
методы, итератор выдаст ConcurrentModificationException
. Таким образом, перед одновременной модификацией итератор быстро и чисто дает сбой, вместо того, чтобы рисковать произвольным недетерминированным поведением в неопределенное время в будущем.
Чтобы исправить эту конкретную ситуацию, вы можете вместо этого использовать собственный метод remove()
Итератора, заменив эту строку:
users.remove(user);
с
it.remove();
Эта последняя операция удаляет из коллекции последний элемент, возвращенный итератором. (Такое использование позволяет избежать исключения, поскольку итератор знает об изменениях и может гарантировать его безопасность; при внешних модификациях итератор не может узнать, является ли состояние его обхода все еще непротиворечивым, и поэтому быстро проваливается).
В некоторых ситуациях это немедленное удаление может оказаться невозможным, и в этом случае существует три альтернативных общих подхода:
- Возьмите копию коллекции (
users
в данном случае), итерируйте по копии и удалите элементы из оригинала .
- Во время итерации создайте набор элементов для удаления, а затем выполните массовое удаление после завершения итерации.
- Используйте реализацию
List
, которая может иметь дело с одновременными изменениями, например CopyOnWriteArrayList
Это довольно распространенный вопрос - см. Также (например) цикл в списке с вопросом о удалении для других ответов.