1

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.

3
  • 1
    "equivalent" == "behaves exactly the same", so that part* of the spec is the 'official' confirmation that it's valid and guaranteed to pick the updated values. Although the part of the spec you quoted is applicable to Iterable's, not arrays - that's further down. Commented Feb 4, 2018 at 16:31
  • What do you mean "would be invalid for e.g. ArrayList"? List<Integer> values = new ArrayList<>(Arrays.asList(6, 5, 3, 2, 2, 4, 0, 1)); for (int value : values) { values.set(value, values.get(value) + 1); } works perfectly fine. You obviously can't use [] on a List, but that's unrelated to the enhanced for loop. Commented Feb 4, 2018 at 19:07
  • @Dukeling, I mean The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Apparently, ArrayList#set is not a structural modification , and so my analogy was admittedly wrong: one cannot structurally modify a Java array. Commented Feb 5, 2018 at 11:07

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.