2009-12-17 8 views
34
for (String fruit : list) 
    { 
     if("banane".equals(fruit)) 
      list.remove(fruit); 
     System.out.println(fruit); 
    } 

Hier eine Schleife mit entfernen Anweisung. Zur Ausführungszeit, erhalte ich einige ConcurrentModificationException, unter der Konsolenausgabe:Schleife auf Liste mit entfernen

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 

Frage: Wie ein Element mit einer Schleife entfernen?

Antwort

76

Sie müssen den Iterator direkt verwenden und das Element über diesen Iterator entfernen.

+0

Denn wer sich erkennen: nicht für die Verwendung mit inkrementellen Index und list.size() !! Ich wollte den Code mit einer foreach-Schleife ändern und es war nicht die richtige Lösung. Dein ist der Eine. – enguerran

+1

ändern Sie einfach 'it.hasNext()' zu 'iterator.hasNext()' und es ist perfekt! (offensichtlich .... aber wer weiß ....) –

4

Verwenden Sie eine for-Schleife, und führen Sie die Auflistung in umgekehrter Reihenfolge durch. (Dies bedeutet, mit dem letzten Element zu beginnen und mit dem ersten Element zu loopen. Dadurch werden keine Probleme durch die Indizes verursacht, die sich aufgrund des Entfernens von Elementen aus der Sammlung ändern.

Sie erhalten die Ausnahme in das Beispiel, das Sie schreiben, weil die Liste, über die Sie Ihre Iterator iteriert, geändert hat, was bedeutet, dass der Iterator ungültig wird.

+0

klingt gefährlich. Wie wäre es mit einer doppelt verknüpften Liste und ähnlichem, wo der Speicher nicht zusammenhängend ist? Ich weiß nicht, ob lists et al in Java "index" haben oder wie "iterator" implementiert ist, aber wenn es wie C++ ist, würde ich überrascht sein, ob Ihr Ansatz mit irgendetwas außer 'ArrayList' funktioniert hat. –

4
for(Iterator<String> iter = list.iterator(); iter.hasNext();) 
{ 
    String fruit = iter.next(); 
    if("banana".equals(fruit)) 
     iter.remove(); 
    System.out.println(fruit); 
} 
6

Neben den Iterator direkt mit (was ich empfehlen würde) können Sie auch speichern Elemente, die Sie in einer anderen Liste entfernen möchten

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

Wohlgemerkt, ich empfehle das nicht, es ist nur eine Alternative. :)

+1

Ihre Lösung ist zu ausführlich – enguerran

+2

Ja, ist es. Deshalb würde ich die "Iterator" -basierte Lösung verwenden, die ich geschrieben habe. – Bombe

+0

Es gibt mehr als einen Weg, es zu tun, aber die meisten dieser Möglichkeiten sind falsch;) – Jorn

1

Ähnlich zu dem, was Bombe vorgeschlagen, aber in weniger Zeilen des Codes durch Iteration auf der Liste kopieren, aber aus der ursprünglichen Liste entfernen;

Ich persönlich denke, das sieht schöner aus als Iteration mit einem Iterator.

+0

Ich denke, es ist einfacher zu lesen – enguerran

+0

Ich würde sagen, das ist Bug anfällig .. mit 2 Listen, wo wir die zweite nicht brauchen. Nur meine 2 Cent. – cheekoo

+0

@cheekoo, ich kann sehen, wie es unnötigen Speicher verwenden würde, aber ich sehe nicht, wie ein kompetenter Entwickler Fehler mit dieser Methode einführen würde. –

10

Das scheint ein bisschen kompliziert, warum nicht einfach eine normale for-Schleife machen? Ich denke, es sieht sauberer aus und wird diesen Fehler nicht werfen. Entschuldige einfach, wenn du etwas entfernst. jedenfalls funktioniert zumindest meine. Diese Art von Auto-Loops sind eher für die Codierung gedacht, dachte ich, also wenn sie nicht bequem sind, dann benutze sie einfach nicht.

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

ist der beste Ansatz ..

Verwandte Themen