Web / Apache Commons Collections Interview questions
How do you troubleshoot a ConcurrentModificationException when using CollectionUtils.filter()?
CollectionUtils.filter(collection, predicate) mutates the collection in place: it walks the collection's own Iterator and calls Iterator.remove() on every element that fails the predicate. A ConcurrentModificationException (CME) shows up when something else disturbs that same collection while filter() is mid-iteration.
// risky: filtering while also iterating the same list elsewhere for (String s : names) { if (s.isEmpty()) { CollectionUtils.filter(names, StringUtils::isNotBlank); // CME } } // safer: snapshot first, or use select() instead of filter() List<String> snapshot = new ArrayList<>(names); Collection<String> kept = CollectionUtils.select(snapshot, StringUtils::isNotBlank);
Common causes are: calling filter() from inside a for-each loop over the same reference, calling it concurrently from another thread without synchronization, or passing a fixed-size/immutable view whose iterator doesn't support remove() at all (which throws UnsupportedOperationException rather than CME, but is diagnosed the same way - check what kind of collection was actually passed in).
The fix is usually one of two things: copy the input into a fresh, independent collection before filtering if the original reference must stay untouched during the operation, or switch to CollectionUtils.select()/selectRejected(), which build and return a brand-new filtered collection instead of mutating the source - sidestepping the in-place removal that causes the CME in the first place.
More Related questions...