Итерируйте по коллекции, выбрав все элементы, которые вы хотите удалить, и поместите их во временную коллекцию. После завершения итерации удалите все найденные элементы из исходной коллекции, используя метод removeAll.
Будет ли это работать для вас? Я имею в виду, не уверен, что логика удаления сложнее, чем в вашем алгоритме.
самый короткий и наиболее эффективный способ:
List & lt; String & gt; list = new CopyOnWriteArrayList & lt; & gt; (); list.removeIf (s - & gt; s.length () & lt; 1);
внутренне создает временный массив с одинаковой длиной и копирует все элементы, где предикат возвращает true.
помните, что если вы используете этот метод для фактической итерации над элементами для выполнения какого-либо действия, эти действия не могут выполняться в paralell больше, поскольку removeIf-вызов является атомарным и блокирует обход для других потоков
Поскольку это CopyOnWriteArrayList, совершенно безопасно удалять элементы при повторении с помощью forEach. Нет необходимости в причудливых алгоритмах.
list.forEach (e - & gt; {if (shouldRemove (e)) list.remove (e);});
EDIT: Ну, конечно, это работает, если вы хотите удалить элементы по ссылке, а не по положению.
Вместо списка можно использовать Queue .
private Queue & lt; Something & gt; queue = new ConcurrentLinkedQueue & lt; Something & gt; ();
Он потокобезопасен и поддерживает iterator.remove ()
. Помните о потокобезопасном поведении итераторов очереди, хотя (проверьте javadoc).
EDIT: Я идиот. Я пропустил тот факт, что это список для копирования на запись, поэтому каждое удаление означает новую копию . Поэтому мои предложения ниже могут быть субоптимальными, если есть несколько удалений.
То же, что и для любого другого списка, итератор которого не поддерживает удаление, или что-либо, где вы не используете итератор. Есть три основных метода, которые приходят на ум, чтобы избежать этой ошибки:
for (int i = 0; i & lt;
... style for for), чтобы вы могли манипулировать индексом. Обычно вы должны перебирать первый элемент сбора, который должен быть удален в отдельном списке, а затем удалять их за пределами каждого цикла (в любом случае это замаскированный цикл на основе итератора)
Что-то вроде этого:
int pos = 0; while (pos & lt; lst.size ()) {Foo foo = lst.get (pos); if (hasToBeRemoved (foo)) {lst.remove (pos); // не перемещать позицию} else {pos ++; }}