boucle sur la liste avec supprimer [dupliquer]

Cette question a déjà une réponse ici:

    for (String fruit : list)
    {
        if("banane".equals(fruit))
            list.remove(fruit);
        System.out.println(fruit);
    }

Voici une boucle avec l'instruction remove. Au moment de l'exécution, j'obtiens une exception ConcurrentModificationException, en dessous de la sortie de la console:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)
at java.util.AbstractList$Itr.next(AbstractList.java:420)
at Boucle.main(Boucle.java:14)
abricot
banane

Question: Comment supprimer un élément avec une boucle?

34
demandé sur Jason C 2009-12-17 14:25:13

7 réponses

Vous devez utiliser l'itérateur directement et supprimer l'élément via cet itérateur.

for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
    String fruit = iterator.next();
    if ("banane".equals(fruit)) {
        iterator.remove();
    }
    System.out.println(fruit);
}
77
répondu Jon Skeet 2009-12-17 12:24:26

, Cela semble un peu compliqué, pourquoi ne pas simplement une boucle for? Je pense qu'il semble plus propre et ne lancera pas cette erreur. Il suffit de décrimenter si vous supprimez quelque chose. au moins le mien fonctionne, de toute façon. Ce genre d'auto-boucles sont plus pour la commodité de codage, je pensais, donc si elles ne sont pas pratiques, alors ne les utilisez pas.

for (int i = list.size() - 1; i>=0; i--) {
    String fruit = list.get(i);
    System.out.println(fruit);

    if ("banane".equals(fruit)) {
        list.remove(fruit);
    }
}
10
répondu steaiii 2015-10-17 12:54:38

En plus d'utiliser le Iterator directement (ce que je recommanderais), vous pouvez également stocker des éléments que vous souhaitez supprimer dans une liste différente.

List<String> toRemove = new ArrayList<String>();
for (String fruit : list) {
    if ("banane".equals(fruit))
        toRemove.add(fruit);
    System.out.println(fruit);
}
for (String fruit : toRemove) {
    list.remove(fruit);
}

Rappelez-vous, je ne recommande pas cela, c'est juste une alternative. :)

6
répondu Bombe 2009-12-17 11:32:39

Utilisez une boucle for et faites une boucle sur la collection dans un ordre inverse. (Cela signifie, commencer par le dernier élément, et boucle au premier élément. Ce faisant, vous n'obtiendrez pas de problèmes par les index qui changent en raison de la suppression d'éléments de la collection.

Vous obtenez l'exception dans l'exemple que vous publiez, car la liste sur laquelle votre itérateur itère a changé, ce qui signifie que l'itérateur devient invalide.

4
répondu Frederik Gheysels 2009-12-17 11:29:31
for(Iterator<String> iter = list.iterator(); iter.hasNext(); )
{
   String fruit = iter.next();
   if("banana".equals(fruit))
      iter.remove();
   System.out.println(fruit);
}
4
répondu Itay Maman 2009-12-17 11:29:42

Similaire à ce que Bombe a suggéré, mais en moins de lignes de code en itérant sur la copie de la liste, mais en supprimant de la liste d'origine;

List<String> temp = new ArrayList<String>(list);
for (String fruit : temp)
{
    if("banane".equals(fruit))
        list.remove(fruit);
    System.out.println(fruit);
}

Personnellement, je pense que cela semble plus agréable que d'itérer avec un itérateur.

1
répondu Tom Neyland 2009-12-17 17:43:25
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
    String s = iter.next();

    if (s.equals("a")) {
        iter.remove();
    }
}

Est la meilleure approche..

1
répondu Xar E Ahmer 2014-06-25 07:29:19