I have learned a lesson at work about what I shouldn't do when using a for-each loop in Java. The for-each loop in Java is used as the following.

for (type var : arr) {
   // body of loop
}

// This is equivalent to the following for loop
for (int i=0; i<arr.length; i++) {
   type var = arr[i];
   // body of loop


The for-each loop structure can be also used with collections. So, it can also be used as the following.
for (type var : coll) {
   // body of loop
}

// This is equivalent to the following for loop using the iterator
for (iterator<type> iter=coll.iterator; iter.hasNext(); ) {
   type var = iter.next();
   // body of loop
}

At work I was working with collections, and had to do an iterative task on the items in the collection. After I finished my code, I tried to execute it and was surprised to see that I got a ConcurrentModificationException.

My shifu(master) at work, advised me that I might be carrying out some operations incorrectly among threads. However, I double checked my critical section points and I found myself doing everything right(probably???)... 

I was tracking down the point where the exception occurred, and finally realized I was doing something I wasn't supposed to do. And yet I was even more surprised to see I wasn't able to find any official technical reference to my mistake.

Here is what I was doing wrong. Some of you might have already figured out the point I'm trying to make from the title of this post. I think you aren't supposed to mess with the iterator of the collection that are using in the for loop.

So here is an example code that I have constructed to illustrate the problem.

public class IteratorTest {
private LinkedList<Integer> list = new LinkedList<Integer>();
public static void main(String[] argv) {
IteratorTest test = new IteratorTest();
test.initList();
test.test();
}

public void initList() {
for (int i=0; i<10; i++) {
list.add(new Integer(i));
}
}

public void test() {
for (Integer i : list) {
if (i.equals(3))
list.remove(list.get(1));
}
}
}

If you execute this short program, this will result in the following error message.
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
at java.util.LinkedList$ListItr.next(Unknown Source)
at IteratorTest.test(IteratorTest.java:18)
at IteratorTest.main(IteratorTest.java:9)

The remove method call on the list will mess with the iterator, and supposedly the ordering of the iterator for the for loop will be corrupted. I guess that is why Java throws a ConcurrentModificationException.

After having to get to know what my problem is, the behavior of how all the for-each loop and the iterator thing works seems so obvious. However, I just think that the for-each loop thing shouldn't be part of the Java language.

Basically, for many of the developers out in the wild, the for-each loop is just another option for the repetition control structure. But, the for-each loop is using the Iterator class for traversing all the items in a collection. While the Iterator class is not part of the language, but a class that is part of the core Java library which is created with the language (I'm not sure if I'm using the correct terminology, but I'm sure you'll get my point), I don't think Java should be supporting this feature. The syntax for the basic control structures should not be dependent to something which is not part of the language itself.

The for-each loop certainly makes the code more simpler and elegant. But I'm not sure what Sun had in mind when they were adding this feature. I'm just curious what people think about my position on the for-each loop and the iterator.

Posted by Dansoonie