views:

49

answers:

4

I've run into this while writing a Traveling Salesman program. For an inner loop, I tried a

for(Point x:ArrayList<Point>){

but when adding another point to that list resulted in a ConcurrentModicationException being thrown.

However, when I changed the loop to

for(int x=0; x<ArrayList<Point>.size(); x++){

the loop ran fine without throwing an exception.

Both a for loops, so why does one throw an exception while the other does not?

+4  A: 

The first example uses an iterator, the second does not. It is the iterator that checks for concurrent modification.

Jim Blackler
A: 

the first code is using an iterator so modifying the collection is not allowed. The second code you are accessing each object with x.get(i), so not using an iterator, modifications thus are allowed

raticulin
A: 

You cannot modify a List while you are iterating over it which you are doing in the first example. In the second you simply have a regular for loop.

fastcodejava
+2  A: 

As others explained, the iterator detects modifications to the underlying collection, and that is a good thing since it is likely to cause unexpected behaviour.

Imagine this iterator-free code which modifies the collection:

for (int x = 0; list.size(); x++)
{
  obj = list.get(x);
  if (obj.isExpired())
  {
    list.remove(obj);
    // Oops! list.get(x) now points to some other object so if I 
    // increase x again before checking that object I will have 
    // skipped one item in the list
  }
}
Martin
I picked your answer because you showed how things could go wrong when iterating as compared to accessing via get()
Jason