In HashSet.java in JDK 1.6, there are some comments about the fail-fast property of HashSet's iterator.
The iterators returned by this class's iterator method are fail-fast: if the set is modified at any time after the iterator is created, in any way except through the iterator's own remove method, the Iterator throws a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
I can understand the above paragraph because It's pretty simple and clear, but I cannot understand the following paragraph. I may understand it if I have some simple examples showing that a fail-fast iterator can even fail.
Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
EDIT: Sorry I used a list, but it's the same idea. This is about iterator, not the Collection behind it.
EDIT2: Also this is far more likely to happen in a multi-threaded environment, where you have two threads, one reading, one writing. These are harder to see when you are coding. To fix those you need to implement Read/Write locks on the list to avoid this.
Here is a code example for the comment:
Iterator itr = myList.iterator();
while(itr.hasNext())
{
Object o = itr.next();
if(o meets some condition)
{
//YOURE MODIFYING THE LIST
myList.remove(o);
}
}
What the specs is saying is that you cannot rely on code like this:
while(itr.hasNext())
{
Object o = itr.next();
try
{
if(o meets some condition)
myList.remove(o);
}
catch(ConcurrentModificationException e)
{
//Whoops I abused my iterator. Do something else.
}
}
Instead you should probably add things to a new list and then switch the myList reference to the one just created. Does that explain the situation?