Concepts / Indexed Loops and Array Traversal

Indexed Loops and Array Traversal

A for-each loop processes the values in an array, not the elements themselves, so assigning to the loop variable does not change the array.

  • Programming

A Loop Variable That Seems to Write Into the Array

A for-each loop looks like it hands you each position of an array, one after another. Because of that, it is tempting to think that writing to the loop variable will write into the array. Many learners expect that a line such as item = 17 inside the loop will fill the array with 17s. This article tests that belief against what the loop actually does, and it shows where the for-each loop is a good fit and where it is not.

What do you think happens?

Before reading on, predict: after this loop runs, what are the values stored in arr?

  • {17, 17, 17}

  • {4, 8, 15}

  • {4, 8, 17}

  • It depends on the length of the array

Reveal answer
Answer:

{4, 8, 15}

The loop variable item is reassigned on each pass, but the array slots are never named in the assignment, so the stored values are unchanged.

java
Output
arr is still {4, 8, 15}
Notes on the code
  • int[] arr declares an array holding three values
  • item receives a value from arr on each pass
  • item = 17 reassigns only the name item
  • The array is unchanged after the loop ends

Tracing the First Pass Through the Loop

Follow the loop one pass at a time. On the first pass, the for-each loop reads the value 4 from the first slot of arr and gives that value to the name item. The statement item = 17 then associates the name item with 17. The array slot that supplied the 4 was never named in that statement, so nothing in the array is reached. The diagram shows the two things side by side: the array has its own slots, and the loop variable is a separate name. Only the name on the left changes.

arr[0]4item17arr[1]8arr[2]15value read on first pass
When the loop variable item is assigned 17 on the first pass, what happens to the array slot it was read from, and why does the array stay the same?

The next pass gives item the next value from the array, 8, and the earlier assignment is simply replaced. The three array cells shown stand in for the full array, and the same reasoning applies to every slot. Only the loop variable is reassigned. The array cells keep the values they had before the loop started.

Values Versus Elements

The key to this topic is a distinction between two words that sound alike in everyday speech. A value is the piece of data stored in a slot. An element is the actual memory location that is part of the array and that holds the value. The array is the collection of these elements, and each element carries one value at a time.

Definition

An element is the memory location that is part of an array and holds a value. A value is the data stored in that location. Assigning a new value to an element changes what the array holds; assigning to a variable that merely received a copy of a value does not.

This distinction explains the whole behavior. A for-each loop works with values. It supplies the value of each element to the loop variable, not the element itself. Because the loop never gives you a handle on the slot, writing to the loop variable has no route back into the array.

Modifying Elements with an Indexed Loop

When the goal is to change the array, the loop has to name the slot being changed. An indexed loop does this by using the index to refer to the element directly. The example below is an illustration written for this article, not an excerpt from the source. It doubles every value in the same array, first with a for-each loop and then with an indexed loop.

java
Output
After the for-each loop: {4, 8, 15}. After the indexed loop: {8, 16, 30}.
Notes on the code
  • The for-each loop reads each value into item, so doubling item changes nothing in arr
  • The indexed loop uses i to name each slot
  • arr[i] on the left side of the assignment is what makes the change stick
arr[0]4arr[0]8arr[1]8arr[1]16arr[2]15arr[2]30arr[0] = arr[0] * 2arr[1] = arr[1] * 2arr[2] = arr[2] * 2
After the indexed loop writes arr[i] on each pass, which stored elements have changed and which values do they now hold?

On each pass, the index i selects one slot, and the assignment writes a new value into that slot. Because the write goes to the element itself, the change remains after the loop ends. The loop variable item in the for-each version was only a copy, so the same arithmetic never reached the array.

Where a For-Each Loop Is Not Suitable

The for-each loop is not always the right tool. There is no simple way to use it to process only part of an array, and it cannot walk the elements in reverse order. Its strength is the opposite case: when you want to process all the values in order, it makes the code a little simpler, because it removes the need for array indices.

values 4, 8, 15whole array, in orderindices 2, 1, 0whole array, reversedindices 1, 2partial range, in order
For an array of three elements, which positions does each loop style visit, and in what order?
java
Notes on the code
  • The start and end bounds of the indexed loop choose which slots are visited
  • A for-each loop has no start or end bound to set
  • Counting the index downward gives reverse order, which the for-each loop cannot provide

Mistakes Beginners Make With For-Each Loops

  • Common mistake

    Assigning to the loop variable and expecting the array to change

    What it looks like
    for (int item : arr) { item = 17; }
    Why it fails

    The loop variable receives a value from the element on each pass. Assigning to it reassigns only the name, and the array slot is never named.

    Do this instead

    Use an indexed loop and assign to the slot, such as arr[i] = 17.

  • Common mistake

    Trying to process only part of the array with a for-each loop

    What it looks like

    Wanting to skip the first element with a for-each loop

    Why it fails

    The for-each loop provides no start or end bounds, so it visits every value in the array.

    Do this instead

    Use an indexed loop with explicit start and end bounds, such as for (int i = 1; i < arr.length; i++).

  • Common mistake

    Expecting a for-each loop to run backward

    What it looks like

    Wanting to print the array from last value to first with a for-each loop

    Why it fails

    The for-each loop moves through values in order and cannot walk the elements in reverse.

    Do this instead

    Use an indexed loop that counts down from arr.length - 1 to 0.

  • Common mistake

    Confusing a value with the element that holds it, which makes the array seem to change or not change for no clear reason

Choosing Between the Two Loop Styles

GoalFor-each loopIndexed loop
Read every value in orderSuitable, and simpler because no indices are neededWorks, but adds index handling
Modify array elementsNot suitable; the loop variable is only a copySuitable; assign to arr[i]
Process only part of the arrayNot suitable; no start or end boundSuitable; set the start and end indices
Walk the array in reverseNot suitableSuitable; count the index downward

Choosing a loop style based on what the loop must do

Practice Predicting Array Contents

MEDIUM

Given int[] scores = {10, 20, 30}; write a loop that adds 5 to every score so that scores ends as {15, 25, 35}. Then explain in one sentence why a for-each loop with item = item + 5 would not achieve this.

Hints
  • Decide whether you need to write to a slot, and use an index to name it
  • Think about what the loop variable holds on each pass

Key Takeaways

  • A for-each loop processes the values in an array, not the elements themselves, so assigning to the loop variable does not change the array.
  • A value is the data stored in a slot, and an element is the memory location that is part of the array and holds that value.
  • To modify array elements, use an indexed loop and assign to the specific slot, such as intList[i].
  • The for-each loop is well suited to reading every value in order, but it is not suitable for partial traversal or reverse order.