views:

83

answers:

1

Before your eyes glaze over at yet another ConcurrentModificationException question, this is not your typical ConcurrentModificationException question.

I understand ConcurrentModificationExceptions but I don't understand why I'm getting one in the following code. In the 'for' below, it appears that the iterator continues to live outside the for loop. (Using the debugger in eclipse, I can see the iterator retains its value of jList's modCount when the loop is restarted.)

public class ForEachTest {
  public static void main(String[] args) {
    List<Integer> zList = new LinkedList<Integer>();
    List<Integer> jList = new LinkedList<Integer>();
    jList.add(1);

    while (true) {
      for (Integer j : jList) {
        zList.add(17);
        System.out.println(j);
      }
      jList = zList;
    }
  }
}

At first I thought this might be an issue of syntactic sugar but I rewrote it using an explicit iterator and ran in to the same behavior.

Finally, I was able to rewrite it by splitting the for into a while with a separate initialization step so I'm not looking for a rewrite merely to get it working. But I would like to know what the problem is with the way its shown here. I would prefer to use the for-each syntax if possible.

+19  A: 

Look at your loop:

while (true) {
  for (Integer j : jList) {
    zList.add(17);
    System.out.println(j);
  }
  jList = zList;
}

On the second iteration of the outer loop, jList and zList refer to the same list (due to the jList = zList; statement)... so when you add to zList inside your inner loop, you're modifying the list you're iterating over. Bang.

Jon Skeet
Beat me to it...I had just finished typing my answer...+1.
Thomas Owens
+1 for being right - nice work, Jon Skeet.
Erick Robertson
That deserves to be accepted. Nothing you could add to that.
serg10
@serg10 Bang needs and exclamation mark.
Andrew