108 votes

Supprimer des éléments d'une liste

En parcourant une liste en boucle, je voudrais supprimer un élément de la liste en fonction d'une condition. Voir le code ci-dessous.

Cela me donne un ConcurrentModification exception.

for (Object a : list) {
    if (a.getXXX().equalsIgnoreCase("AAA")) {
        logger.info("this is AAA........should be removed from the list ");
        list.remove(a);
    }
}

Comment cela peut-il être fait ?

228voto

Joop Eggen Points 30166
for (Iterator<String> iter = list.listIterator(); iter.hasNext(); ) {
    String a = iter.next();
    if (...) {
        iter.remove();
    }
}

En supposant en outre que la liste est constituée de chaînes de caractères. Comme déjà répondu, un list.iterator() est nécessaire. Le site listIterator peut aussi faire un peu de navigation.

----------

Mise à jour

Comme l'a fait remarquer @AyushiJain, il y a

list.removeIf(...);

76voto

Nambari Points 42066

Vous devez utiliser Iterator et appeler remove() en iterator au lieu d'utiliser for boucle.

33voto

Vous ne pouvez pas le faire parce que vous êtes déjà en train de boucler dessus.

Afin d'éviter cette situation, utilisez l'Iterator, qui vous garantit de retirer l'élément de la liste en toute sécurité ...

List<Object> objs;
Iterator<Object> i = objs.iterator();
while (i.hasNext()) {
   Object o = i.next();
  //some condition
    i.remove();
}

21voto

André Stannek Points 3701

Vous ne pouvez pas et ne devez pas modifier une liste tout en la parcourant. Vous pouvez résoudre ce problème en enregistrant temporairement les objets à supprimer :

List<Object> toRemove = new ArrayList<Object>();
for(Object a: list){
    if(a.getXXX().equalsIgnoreCase("AAA")){
        toRemove.add(a);
    }
}
list.removeAll(toRemove);

7voto

Bart Enkelaar Points 695

Outre toutes les excellentes solutions proposées ici, j'aimerais proposer une solution différente.

Je ne suis pas sûr que vous soyez libre d'ajouter des dépendances, mais si c'est le cas, vous pourriez ajouter le fichier https://code.google.com/p/guava-libraries/ en tant que dépendance. Cette bibliothèque ajoute le support de nombreuses opérations fonctionnelles de base à Java et peut rendre le travail avec les collections beaucoup plus facile et plus lisible.

Dans le code, j'ai remplacé le type de la liste par T, car je ne sais pas en quoi votre liste est typée.

Ce problème peut, avec la goyave, être résolu de la manière suivante :

List<T> filteredList = new Arraylist<>(filter(list, not(XXX_EQUAL_TO_AAA)));

Et ailleurs, vous définissez XXX_EQUAL_TO_AAA comme suit :

public static final Predicate<T> XXX_EQUAL_TO_AAA = new Predicate<T>() {
    @Override
    public boolean apply(T input) {
        return input.getXXX().equalsIgnoreCase("AAA");
    }
}

Cependant, c'est probablement excessif dans votre situation. C'est simplement quelque chose qui devient de plus en plus puissant à mesure que vous travaillez avec des collections.

Ohw, aussi, vous avez besoin de ces importations statiques :

import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Collections2.filter;

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