The iterator does NOT support the remove method.
But why does it work in enhanced-for loop?
List<String> lst = new CopyOnWriteArrayList<>();
lst.add("one");
lst.add("two");
lst.add("three");
for (String str : lst) {
if (str.equals("one")) {
lst.remove("two"); // no ConcurrentModificationException
}
}
System.out.println(lst); // [one, three] => removed "two" !
List<String> lst = new ArrayList<>();
would generate ConcurrentModificationException
Javadoc clearly states that CopyOnWriteArrayList.iterator()
does not support remove()
=> it shall throw UnsupportedOperationException
! I understand it is weakly consistent - say there is no ConcurrentModificationException
if I add elements to CopyOnWriteArrayList after I obtained an iterator from that CopyOnWriteArrayList
P.S. Sorry, I was inattentive - I called remove() not on the iterator! I was confused by being inside enhanced-for (it uses an iterator implicitly).
CopyOnWriteArrayList iterator fail safe implementation supports modify actions.
When you iterate over a CopyOnWriteArrayList and CopyOnWriteArraySet the iterator uses a snapshot of the underlying list (or set) and does not reflect any changes to the list or set after the snapshot was created. The iterator will never throw a ConcurrentModificationException.
Read more at: https://markusjais.com/java-concurrency-understanding-copyonwritearraylist-and-copyonwritearrayset/
By the way, in classic List implementation like ArrayList() etc, you don't need to use iterator explicitly. Use list.removeIf(predicate) method.