Using for(Type x:collection){...}
which widely used collection types make removing x
safe during iteration?
And is there a technical term for this to look out for in the JavaDocs?
Clarification:
I initially only asked about using the for-each syntax for(Type x:collection){...}
. However a more complete answer would describe this style AND using a normal Iterator-based loop where there are differences... the question is more about which standard Collections allow me to remove elements during iteration, AND how to perform the iteration to allow this.
Fail-Safe iterators don't throw any exceptions if a collection is structurally modified while iterating over it. This is because, they operate on the clone of the collection, not on the original collection and that's why they are called fail-safe iterators.
Iterator can only move to next() element or remove() an element. However Collection can add(), iterate, remove() or clear() the elements of the collection.
An element can be removed from a Collection using the Iterator method remove(). This method removes the current element in the Collection. If the remove() method is not preceded by the next() method, then the exception IllegalStateException is thrown.
Iterator allows the caller to remove elements from the given collection during iterating over the elements.
One such collection is CopyOnWriteArrayList
. Other collections in the java.util.concurrent
package share this feature.
The fact that their iterators never throw a ConcurrentModificationException
is a side-effect of the copy-on-write semantics of this class: every time you modify it, the underlying array will be copied. This is done to allow fast concurrent access to often-read but rarely-modified lists.
The JavaDoc explains it like this (emphasis mine):
The "snapshot" style iterator method uses a reference to the state of the array at the point that the iterator was created. This array never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw
ConcurrentModificationException
.
In addition to the high costs of updates this implementation has some further drawbacks:
The iterator will not reflect additions, removals, or changes to the list since the iterator was created. Element-changing operations on iterators themselves (
remove
,set
, andadd
) are not supported. These methods throwUnsupportedOperationException
.
Note that those collections are not meant to be utility to allow "easy" looping-and-removal, but are specialized collections for use in high-concurrency situations where many threads need concurrent access to data that can still change (but usually changes rarely). Do not simply replace every ArrayList
with a CopyOnWriteArrayList
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With