I have heard (read) many times that one must not 1. modify 2. delete an element from a list when iterating over it using the enhanced for loop, for example http://jmonkeyengine.com/mark/?p=147. I am clear with the second point of the rule: not to delete an element from a list while iterating over it. But I never came across a suitable example illustrating the 'modify' operation on the list. Specifically I would like to know whether the following use of enhanced for loop is a valid one.
The code above runs fine and prints a list whose every element has the instance variable 'val' set to the integer 2, which is what I expected to happen. But I don't know whether this code is working fine as a special case or is it the norm. I will repeat my question here: Have I transgressed the rule to not to modify a list while iterating over it using the enhanced for loop?
Now my second question is: If the code above doesn't illustrate the wrong practice of modifying a list while iterating over it using the enhanced for loop then what does?
[ May 04, 2008: Message edited by: Ganesh Hegde ] [ May 04, 2008: Message edited by: Ganesh Hegde ]
As I understand it, the variable in the enhanced for loop is akin to a parameter passed to a method or constructor: changes to the state of the referenced object are permitted, but assigning a new object will not cause the new object to be assigned to the collection element.
In your code, instead of it.val = 2; if you execute
there is no change in the list elements, the original values continue to exist.
The point here is that changing the state of an object which happens to be a list element does not constitute modifying the list, as the list merely holds references to its elements.
Sorry if that's not as clearly expressed as I would have liked it to be, but I think you can get the idea.
There are no new questions, but there may be new answers.
Joined: Apr 09, 2008
Yes Darryl, I think you are right. I was a bit confused with how people express the rule (which I stated at the onset of this thread). I have heard people say that you 'are not allowed' to modify a list when iterating with the for loop (enhanced for). But I feel it should rather be: you 'cannot' modify a list when iterating with the enhanced for. I feel this subtle difference in wording is important because as you say one is uselessly assigning a local variable 'it' with a newly created object in the code here:
Nothing's going to happen to the original list.
But if you word the rule as: you 'are not allowed' to modify a list while iterating with an enhanced for loop, then we expect some risk (an exception like the 'ConcurrentModificationException') when trying to run the above piece of code. I tried to search out the rule in both the Sun's Java tutorial and the language specification but failed to get one.
Modifying items in an array will likely not cause problems.
Where it could be problematic is in collections that maintain an order, or particularly are HASHed.
A HashSet would be most likely the one you need to be careful of. Since you may only know you have a Set, you might not be sure what you are handling is hashed.
If you change the value of the object in a way that will change the hash value, then all of a sudden the collection cannot find things it's looking for, and will get very confused.
Bill Shirley - bshirley - frazerbilt.com
if (Posts < 30) you.read( JavaRanchFAQ);
Joined: Apr 09, 2008
Well, actually I was talking about the basic iterator behaviour which the enhanced for loop uses under the hood. And I don't think the iterator's behaviour depends on the way things are added in the collection over which the iteration is being done. For example, I have modified the above code to make use of the HashSet instead of the ArrayList.
This code runs fine and produces the expected output. What I am trying to achieve in the above code is that in spite of changing the states of the objects in the set, the enhanced for loop is working fine. I am changing the state of each object in such a way that the hashcode of the object also changes.
Here you go, a junit 4 test that may help someone. But I encourage you to try this yourself, as that's the key to learning.
Joined: Apr 09, 2008
Jonathan, if I get you right, the code that you produced establishes that removing or deleting an element from a collection while iterating with the enhanced for loop throws the ConcurrentModificationException.
But what do you say about what Darryl pointed out earlier in this thread, a change in the state of an object cannot throw an exception irrespective of the type of collection the object is contained in.