Regel
Verwendung sichere Methoden bei Entfernen von Sammlungen
Ändern einer Sammlung während Durchlaufen über sie oft Fehler Fehler.
Unterstützte Sprachen: PY, Java, C/C++, C#,
Swift/Objective-C, Ruby, PHP, Kotlin, Go,
Scala, Rust, Groovy, Dart, Julia, Elixit,
Erlang, Clojure, OCaml, LuaEinleitung
Das Entfernen von Elementen aus einer Collection während der Iteration führt zu ConcurrentModificationExceptions in Java und unvorhersehbarem Verhalten in C#. Der Iterator verwaltet einen internen Zeiger, der ungültig wird, wenn sich die zugrunde liegende Collection ändert. Dies führt zu übersprungenen Elementen, Abstürzen oder Endlosschleifen, abhängig vom Collection-Typ und dem verwendeten Entfernungsmuster.
Warum es wichtig ist
Systemstabilität: Concurrent Modification Exceptions bringen die Anwendung sofort zum Absturz. Im Produktivbetrieb bedeutet dies verworfene Anfragen und Service-Nichtverfügbarkeit. Die Ausnahme tritt oft in Randfällen mit spezifischen Daten auf, was es schwierig macht, sie während des Testens zu erkennen.
Datenintegrität: Wenn die Entfernungslogik mitten in einer Iteration fehlschlägt, bleibt die Sammlung in einem teilweise modifizierten Zustand zurück. Einige Elemente werden entfernt, während andere, die hätten entfernt werden sollen, verbleiben. Dies erzeugt inkonsistente Daten, die die nachgeschaltete Logik beeinflussen.
Debugging-Komplexität: Fehler bei gleichzeitiger Modifikation sind zeitabhängig und treten möglicherweise nur bei bestimmten Datenkombinationen auf. Sie sind schwer konsistent zu reproduzieren, was das Debugging und die zuverlässige Behebung erschwert.
Code-Beispiele
❌ Nicht konform:
List<User> users = getUserList();
for (User user : users) {
if (!user.isActive()) {
users.remove(user); // ConcurrentModificationException
}
}
Warum es falsch ist: Entfernen aus Benutzer während die Iteration mit einer erweiterten for-Schleife verursacht ConcurrentModificationException. Der Iterator erkennt, dass die Collection außerhalb des Iterators modifiziert wurde und wirft sofort eine Exception. Alle aktiven Benutzer nach dem ersten inaktiven werden niemals verarbeitet.
✅ Konform:
List<User> users = getUserList();
Iterator<User> iterator = users.iterator();
while (iterator.hasNext()) {
User user = iterator.next();
if (!user.isActive()) {
iterator.remove(); // Safe removal through iterator
}
}
Warum dies wichtig ist: Nutzung iterator.remove() entfernt Elemente sicher während der Iteration. Der Iterator behält einen konsistenten Zustand bei und verarbeitet die verbleibenden Elemente weiter. Alle inaktiven Benutzer werden korrekt und ohne Ausnahmen entfernt.
Fazit
Verwenden Sie Iteratoren remove() Methode für sicheres Entfernen während der Iteration. Alternativ verwenden Sie Streams mit filter() um neue Sammlungen zu erstellen oder removeIf() für die Massenentfernung. Rufen Sie niemals die Sammlung auf remove() direkt während der Iteration.
.avif)
