Alexey
Alexey

Reputation: 9447

Is it valid to modify array elements while iterating with 'enhanced for' in Java?

Cosider this code:

    for (int value : values) {
        values[value] = -values[value] - 1;
    }

Is it guaranteed to pick updated values when the iteration process reaches appropriate elements?

Experimentally I figured ut that it works as expected (iteration yields the updated values).

Also from Java spec I can conclude that it should work:

The enhanced for statement is equivalent to a basic for statement of the form:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
    {VariableModifier} TargetType Identifier =
        (TargetType) #i.next();
    Statement
}

I just wonder, if there is an 'official' confirmation that it's valid and guaranteed to pick the updated values?

Update: Excluded according to comments:

I am in doubt because analogous code would be invalid for e.g. ArrayList.

Upvotes: 1

Views: 2739

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726639

Short answer: yes, it is guaranteed to pick up the updated value.

Long answer: an enhanced for on an array is equivalent to this code (see this documentation, scroll down to "Otherwise, the Expression necessarily has an array type" part):

T[] #a = Expression;
for (int #i = 0; #i < #a.length; #i++) {
    VariableModifiersopt TargetType Identifier = #a[#i];
    ...
}

Therefore, it behaves the same way as if the array was iterated using an index.

Note: One thing that would be illegal is replacing the whole array that you are iterating with a new array object, i.e. assigning values = new int[...] has a potential of going past the end of the newly allocated array.

Upvotes: 1

Suresh Atta
Suresh Atta

Reputation: 121998

Reading source code can confirm this.

Yes it is.

Just look at the source code of next() method. It keep on getting the data from ArratList

Object[] elementData = ArrayList.this.elementData;

Full method

@SuppressWarnings("unchecked")
753         public E More ...next() {
754             checkForComodification();
755             int i = cursor;
756             if (i >= size)
757                 throw new NoSuchElementException();
758             Object[] elementData = ArrayList.this.elementData;
759             if (i >= elementData.length)
760                 throw new ConcurrentModificationException();
761             cursor = i + 1;
762             return (E) elementData[lastRet = i];
763         }

That tells that, if you are modifying an element in side ArrayList while iterating, you see those changes right away.

Upvotes: 0

Related Questions