Wie kann man in Java Elemente aus einer Liste in einer Schleife entfernen?

Wenn man in einer Schleife Elemente aus einer Liste entfernen möchte, bekommt in der Regel (aber komischerweise nicht immer) die ConcurrentModificationException:

List<String> test = new ArrayList<>(Arrays.asList("Foo", "Bar", "Baz"));

for (String str : test) {
	if (str.equals("Foo")) {
		test.remove(str);
		// ConcurrentModificationException
	}
}

Mit "Bar":

if (str.equals("Bar")) {
		test.remove(str);
		// Läuft durch?!
	}

passiert es aber nicht. Warum?

Alle Kommentare
javaguy Jul 7 (22:28)

Dazu gibt es verschiedene Möglichkeiten:

Mit dem Iterator

Iterator<String> testIterator = test.iterator();
while(testIterator.hasNext()) {     
    String t = testIterator.next();     
    if ("Bar".equals(t)) {
        fruitIterator.remove();
    } 
}

Diese Methode funktioniert aber nicht immer. Für zB. Arrays.asList(...) kommt hier UnsupportedOperationException.

Am einfachsten funktioniert es mit Streams ab Java 8:

List<String> ohneBar =  test
    .stream()
    .filter(t -> !"Bar".equals(t))
    .collect(Collectors.toList());

oder mit removeIf ("Bar" und "Baz" aus der Liste entfernt)

test.removeIf(t -> t.equals("Bar") || t.equals("Baz"))
0 0 0
Noch keine Stimmen abgegeben
TheSupervisor Jul 7 (22:45)

Es geht auch mit normalen for-Schleifen. Mit rückwärts Iterieren:

for (int i = (test.size() - 1); i >=0; i--) {
    if ("Bar".equals(test.get(i))) {
         test.remove(i);
    }
}

Während der Iteration ändert sich Länge des Arrays (von 3 auf 2 in diesem Beispiel). Aber dadurch, dass wir rückwärts Iterieren, wir die "size" Methode nur bei der Initialisierung der Zählvariable benötigt.

Das Entfernen funktioniert auch beim "normalen"-Iterieren, man muss dann aber immer die Zählvariable anpassen (weil die Schleifen-Bedingung bei jedem Durchlauf evaluiert wird):

for (int i = 0; i < test.size(); i++) {
    if ("Bar".equals(test.get(i))) {
         test.remove(i);
         i--;
    }     
}
0 0 0
Noch keine Stimmen abgegeben
Durch die Nutzung dieser Website erklären Sie sich mit der Verwendung von Cookies einverstanden. Außerdem werden teilweise auch Cookies von Diensten Dritter gesetzt. Genauere Informationen finden Sie in unserer Datenschutzerklärung sowie im Impressum.