250 votes

Comment éviter l'exception java.util.ConcurrentModificationException lors de l'itération et de la suppression d'éléments d'une ArrayList ?

J'ai une liste de tableaux que je veux parcourir par itération. Pendant cette itération, je dois supprimer des éléments en même temps. Évidemment, cela génère un java.util.ConcurrentModificationException .

Quelle est la meilleure pratique pour gérer ce problème ? Devrais-je d'abord cloner la liste ?

Je supprime les éléments non pas dans la boucle elle-même mais dans une autre partie du code.

Mon code ressemble à ceci :

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 pourrait appeler Test.removeA() ;

0voto

"Dois-je cloner la liste en premier ?"

C'est la solution la plus simple : supprimer le clone et le recopier après l'avoir supprimé.

Un exemple tiré de mon jeu 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();
}

0voto

J'arrive tard je sais mais je réponds à cette question car je pense que cette solution est simple et élégante :

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);
}

Tout ceci est pour la mise à jour d'une liste à l'autre et vous pouvez tout faire à partir d'une seule liste. et dans la méthode de mise à jour vous vérifiez les deux listes et vous pouvez effacer ou ajouter des éléments entre les listes. Cela signifie que les deux listes ont toujours la même taille.

0voto

user8009263 Points 11

Utiliser un Iterator au lieu d'une liste de tableaux

Conversion d'un ensemble en itérateur avec correspondance de type

Et passer à l'élément suivant et supprimer

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

Le passage au suivant est important ici car il doit prendre l'index pour supprimer l'élément.

-1voto

Gibolt Points 4072

Si votre objectif est de supprimer tous les éléments de la liste, vous pouvez itérer sur chaque élément, puis appeler :

list.clear()

-1voto

chepe lucho Points 704

Qu'en est-il de

import java.util.Collections;

List<A> abc = Collections.synchronizedList(new ArrayList<>());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X