Как избежать java.util.ConcurrentModificationException при переборе и удалении элементов из ArrayList - PullRequest
169 голосов
/ 12 ноября 2011

У меня есть ArrayList, который я хочу перебрать.Итерируя по нему, я должен удалить элементы одновременно.Очевидно, это выдает java.util.ConcurrentModificationException.

. Каков наилучший метод для решения этой проблемы?Должен ли я сначала клонировать список?

Я удаляю элементы не в самом цикле, а в другой части кода.

Мой код выглядит так:

public class Test() {
    private ArrayList<A> abc = new ArrayList<A>();

    public void doStuff() {
        for (A a : abc) 
        a.doSomething();
    }

    public void removeA(A a) {
        abc.remove(a);
    }
}

a.doSomething может позвонить Test.removeA();

Ответы [ 18 ]

2 голосов
/ 10 сентября 2016

Сделайте что-нибудь простое, как это:

for (Object object: (ArrayList<String>) list.clone()) {
    list.remove(object);
}
1 голос
/ 01 февраля 2018

Альтернативное решение Java 8 с использованием потока:

        theList = theList.stream()
            .filter(element -> !shouldBeRemoved(element))
            .collect(Collectors.toList());

В Java 7 вы можете использовать вместо Guava:

        theList = FluentIterable.from(theList)
            .filter(new Predicate<String>() {
                @Override
                public boolean apply(String element) {
                    return !shouldBeRemoved(element);
                }
            })
            .toImmutableList();

Обратите внимание, что пример Guava приводит к неизменному списку, который может или не может быть тем, что вы хотите.

0 голосов
/ 18 февраля 2019

Вы также можете использовать CopyOnWriteArrayList вместо ArrayList. Это последний рекомендуемый подход, начиная с JDK 1.5 и далее.

0 голосов
/ 14 декабря 2018

Использование Итератора вместо списка массивов

Преобразование набора в итератор с типом соответствия

И переход к следующему элементу и удаление

Iterator<Insured> itr = insuredSet.iterator();
while (itr.hasNext()) { 
    itr.next();
    itr.remove();
}

Переходздесь важно следующее, так как для удаления элемента необходимо использовать индекс.

0 голосов
/ 09 ноября 2018

Просто добавьте break после вашего ArrayList.remove (A) оператора

0 голосов
/ 11 сентября 2018

Я опаздываю, знаю, но отвечаю на это, потому что считаю это решение простым и элегантным:

List<String> listFixed = new ArrayList<String>();
List<String> dynamicList = new ArrayList<String>();

public void fillingList() {
    listFixed.add("Andrea");
    listFixed.add("Susana");
    listFixed.add("Oscar");
    listFixed.add("Valeria");
    listFixed.add("Kathy");
    listFixed.add("Laura");
    listFixed.add("Ana");
    listFixed.add("Becker");
    listFixed.add("Abraham");
    dynamicList.addAll(listFixed);
}

public void updatingListFixed() {
    for (String newList : dynamicList) {
        if (!listFixed.contains(newList)) {
            listFixed.add(newList);
        }
    }

    //this is for add elements if you want eraser also 

    String removeRegister="";
    for (String fixedList : listFixed) {
        if (!dynamicList.contains(fixedList)) {
            removeResgister = fixedList;
        }
    }
    fixedList.remove(removeRegister);
}

Все это для обновления из одного списка в другой, и вы можете сделать все из одного спискаи при обновлении метода вы проверяете оба списка и можете стирать или добавлять элементы между списком.Это означает, что оба списка всегда имеют одинаковый размер

0 голосов
/ 21 августа 2018

Если ваша цель состоит в том, чтобы удалить все элементы из списка, вы можете выполнить итерацию по каждому элементу, а затем вызвать:

list.clear()
0 голосов
/ 30 апреля 2013

«Должен ли я сначала клонировать список?»

Это будет самое простое решение, удалить из клона и скопировать клон обратно после удаления.

Пример из моей игры на rummikub:

SuppressWarnings("unchecked")
public void removeStones() {
  ArrayList<Stone> clone = (ArrayList<Stone>) stones.clone();
  // remove the stones moved to the table
  for (Stone stone : stones) {
      if (stone.isOnTable()) {
         clone.remove(stone);
      }
  }
  stones = (ArrayList<Stone>) clone.clone();
  sortStones();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...