Rule
Use safe methods when removing from collections.
Modifying a collection while iterating over it often causes bugs.
Supported languages: PY, Java, C/C++, C#,
Swift/Objective-C, Ruby, PHP, Kotlin, go,
Scala, Rust, Groovy, Dart, Julia, Elixit,
Erlang, Clojure, OCaml, LuaIntroduction
Removing items from a collection during iteration causes concurrent modification exceptions in Java and unpredictable behavior in C#. The iterator maintains an internal pointer that becomes invalid when the underlying collection changes. This leads to skipped elements, crashes, or infinite loops depending on the collection type and removal pattern used.
Why it matters
System stability: Concurrent modification exceptions crash the application immediately. In production, this means dropped requests and service unavailability. The exception often occurs in edge cases with specific data, making it difficult to catch during testing.
Data integrity: When removal logic fails mid-iteration, the collection is left in a partially modified state. Some items are removed while others that should have been removed remain. This creates inconsistent data that affects downstream logic.
Debugging complexity: Concurrent modification bugs are timing-dependent and may only manifest with certain data combinations. They're difficult to reproduce consistently, making them hard to debug and fix reliably.
Code examples
❌ Non-compliant:
List<User> users = getUserList();
for (User user : users) {
if (!user.isActive()) {
users.remove(user); // ConcurrentModificationException
}
}
Why it's wrong: Removing from users while iterating with enhanced for-loop causes ConcurrentModificationException. The iterator detects that the collection was modified outside the iterator and throws immediately. Any active users after the first inactive one are never processed.
✅ Compliant:
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
}
}
Why this matters: Using iterator.remove() safely removes items during iteration. The iterator maintains consistent state and continues processing remaining items. All inactive users are correctly removed without exceptions.
Conclusion
Use iterator's remove() method for safe removal during iteration. Alternatively, use streams with filter() to create new collections or removeIf() for bulk removal. Never call collection's remove() directly while iterating.
.avif)
