([[][a-z \s]+[]])
Выше должно работать, учитывая следующее объяснение
Для безопасного удаления из коллекции во время итерации по ней вы должны использовать итератор.
Например:
List<String> names = ....
Iterator<String> i = names.iterator();
while (i.hasNext()) {
String s = i.next(); // must be called before you can call i.remove()
// Do something
i.remove();
}
Из Документации Java :
итераторы, возвращаемые итератором этого класса и listIterator методы работают без сбоев: если список структурно изменен в любом время после создания итератора любым способом, кроме собственные методы удаления или добавления итератора, итератор выдаст ConcurrentModificationException. Таким образом, перед лицом одновременного модификации, итератор выходит из строя быстро и чисто, а не рисковать произвольным, недетерминированным поведением в неопределенное время в будущем.
Возможно, для многих новичков непонятно, что итерация по списку с использованием конструкций for / foreach неявно создает итератор, который обязательно недоступен. Эту информацию можно найти здесь
Java-дизайн «расширенного цикла for» заключался в том, чтобы не подвергать итератор коду, но единственный способ безопасно удалить элемент - это получить доступ к итератору. Так что в этом случае вы должны сделать это по-старому:
for(Iterator<String> i = names.iterator(); i.hasNext();) {
String name = i.next();
//Do Something
i.remove();
}
Если в реальном коде усовершенствованный цикл for действительно того стоит, тогда вы можете добавить элементы во временную коллекцию и вызвать removeAll в списке после цикла.
РЕДАКТИРОВАТЬ (повторное добавление): Нет, изменение списка каким-либо образом за пределами метода iterator.remove () во время итерации вызовет проблемы. Единственный способ обойти это - использовать CopyOnWriteArrayList, но он действительно предназначен для решения проблем параллелизма.
Самый дешевый (с точки зрения количества строк кода) способ удаления дубликатов - выгрузить список в LinkedHashSet (а затем обратно в Список при необходимости). Это сохраняет порядок вставки при удалении дубликатов.
Вы не хотите этого делать . Это может вызвать неопределенное поведение в зависимости от коллекции. Вы хотите напрямую использовать итератор . Хотя конструкция for each является синтаксическим сахаром и на самом деле использует итератор, она скрывает его от вашего кода, поэтому вы не можете получить к нему доступ для вызова Iterator.remove
.
Итератор работает так же. не указано, если основной коллекция изменяется, пока итерация выполняется любым способом кроме вызова этого метода.
Вместо этого напишите свой код:
List<String> names = ....
Iterator<String> it = names.iterator();
while (it.hasNext()) {
String name = it.next();
// Do something
it.remove();
}
Обратите внимание, что код вызывает Iterator.remove
, а не List.remove
.
Добавление:
Даже если вы удаляете элемент, который еще не был повторен, вы все равно не хотите изменять коллекцию, а затем использовать Iterator
. Это может изменить коллекцию неожиданным образом и повлиять на будущие операции в Iterator
.
Те, кто говорят, что вы не можете безопасно удалить элемент из коллекции, кроме как с помощью Iterator, не совсем верны, вы можете сделать это безопасно, используя одну из параллельных коллекций, такую как ConcurrentHashMap.