web-dev-qa-db-fra.com

Supprimer des éléments d'une liste

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

Cela me donne une exception ConcurrentModification.

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?

100
Techie

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

70
kosa
for (Iterator<String> iter = list.listIterator(); iter.hasNext(); ) {
    String a = iter.next();
    if (...) {
        iter.remove();
    }
}

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

210
Joop Eggen

Vous ne pouvez pas le faire car vous le faites déjà.

Afin d'éviter cette situation, utilisez Iterator, qui vous garantit de supprimer 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();
}
28
Suresh Atta

Vous ne pouvez pas et ne devriez pas modifier une liste 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);
18
André Stannek

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

Je ne sais pas si vous êtes libre d'ajouter des dépendances, mais si vous le pouviez, vous pouvez ajouter le https://code.google.com/p/guava-libraries/ en tant que dépendance. Cette bibliothèque ajoute la prise en charge de nombreuses opérations fonctionnelles de base à Java et permet de travailler avec des collections beaucoup plus facilement et plus lisiblement.

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

Ce problème peut être résolu comme ceci avec la goyave:

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

Et ailleurs, vous définissez ensuite 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 exagéré dans votre situation. C'est simplement quelque chose qui devient de plus en plus puissant à mesure que vous travaillez avec des collections.

Ohw, vous avez également besoin de ces importations statiques:

import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Collections2.filter;
7
Bart Enkelaar
//first find out the removed ones

List removedList = new ArrayList();
for(Object a: list){
    if(a.getXXX().equalsIgnoreCase("AAA")){
        logger.info("this is AAA........should be removed from the list ");
        removedList.add(a);

    }
}

list.removeAll(removedList);
5
Makky