Wenn ich diesen Code ausführe, werfe ich a ConcurrentModificationException.
Es sieht so aus, als wenn ich das angegebene Element aus der entferne listdas list weiß es nicht size wurden geändert.
Ich frage mich, ob dies ein allgemeines Problem mit ist collections und Elemente entfernen?
Paul Segen
Ich glaube, das ist der Zweck hinter dem Iterator.remove() -Methode, um ein Element während der Iteration aus der Sammlung entfernen zu können.
Beispielsweise:
Iterator<String> iter = li.iterator();
while(iter.hasNext()){
if(iter.next().equalsIgnoreCase("str3"))
iter.remove();
}
Leider gibt es in der Foreach-Schleife keinen Zugriff auf den zugrunde liegenden Iterator, also iterator.remove() ist versteckt.
– akf
25. Februar 11 um 2:59 Uhr
Nun ja, Sie könnten die for-each-Schleife nicht verwenden, Sie müssten zur Verwendung von wechseln Iterator.
– Paul Segen
25. Februar 11 um 3:04 Uhr
@afk, Ja, Sie müssten auf die Verwendung eines Iterators umsteigen. Denken Sie daran, dass die For-Each-Schleife nur syntaktischer Zucker ist. Dies wäre einer der Fälle, in denen es eindeutig keinen Sinn macht, diese Syntax zu verwenden.
– Tim Bender
25. Februar 11 um 3:46 Uhr
iter.remove() führt ebenfalls zu dieser Ausnahme.
– Amalgowinus
4. April 16 um 20:53 Uhr
bigdev.de
Die Java 8-Methode, um es ohne Iterator aus der Liste zu entfernen, ist:
li.removeIf(<predicate>)
dh
List<String> li = new ArrayList<String>();
// ...
li.removeIf(st -> !st.equalsIgnoreCase("str3"));
Beachten Sie, dass diese Ausnahme nicht immer anzeigt, dass ein Objekt gleichzeitig von einem anderen Thread geändert wurde. Wenn ein einzelner Thread eine Folge von Methodenaufrufen ausgibt, die den Vertrag eines Objekts verletzt, kann das Objekt diese Ausnahme auslösen. Wenn beispielsweise ein Thread eine Sammlung direkt ändert, während er mit einem Fail-Fast-Iterator über die Sammlung iteriert, gibt der Iterator diese Ausnahme aus
Ja, Leute stoßen darauf – das Problem ist, dass Sie die Liste nicht ändern können, während Sie darüber iterieren. Ich habe in der Vergangenheit 2 Alternativen verwendet:
Sie können die Indizes der Elemente verfolgen, die Sie entfernen möchten, und sie dann entfernen, nachdem Sie die Iteration abgeschlossen haben.
Oder Sie können alle, die Sie behalten möchten, in eine neue Liste kopieren, während Sie iterieren, und dann die alte Liste verwerfen, wenn Sie fertig sind.
Diese Optionen gehen davon aus, dass Sie die Liste durchlaufen müssen, um die zu entfernenden Elemente zu finden – nützlich in Fällen, in denen die Listenelemente komplexe Objekte mit Eigenschaften sind, die Sie testen könnten.
In Ihrem speziellen Fall müssen Sie nicht einmal iterieren, da Sie einfach removeAll verwenden können. Sehen Sie sich die API an Hier. Es gibt auch raffinierte Methoden wie “retainAll”, die alles verwerfen, was nicht im Argument steht. Sie können remove/retain-ähnliche Methoden immer dann verwenden, wenn die Objekte in der Liste Gleichheit und Hashcode richtig implementieren. Wenn Sie sich nicht auf Equals/Hashcode verlassen können, um die Gleichheit zwischen Instanzen in Ihrer App zu identifizieren, müssen Sie die Entfernung selbst vornehmen….
Versuchen Sie dies (Java 8):
list.removeIf(condition);
Stakahop
Sie können direkt in der for-each-Schleife eine Kopie der Liste erstellen, aus der Sie Elemente entfernen möchten. Für mich ist das der einfachste Weg. Etwas wie das:
for (String stringIter : new ArrayList<String>(myList)) {
myList.remove(itemToRemove);
}
Hoffe das hilft dir..
gdogaru
Erwähnenswert finde ich die Version Java 8
@Test
public void testListCur() {
List<String> li = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
li.add("str" + i);
}
li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList());
System.out.println(li);
}
oder einfach verwenden li.removeIf…
– Benutzer2336315
23. Juni 14 um 18:44 Uhr
.
7577800cookie-checkWird beim Entfernen eines Elements aus einer java.util.List während der Listeniteration eine ConcurrentModificationException ausgelöst? [duplicate]yes