Introduction to For-each Loops for Array Processing
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 Tempting Assumption About Loop Variables
A for-each loop seems to hand you each position of an array, one after another. Because of that, it is natural to expect 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 lesson 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?
Inside a for-each loop over an array, the body runs item = 17. What happens to the array?
Reveal answer
The array keeps its original values, and only item changes.
The for-each loop supplies values to the loop variable. The assignment item = 17 gives the name item the value 17, but it never names the array slot that supplied the value, so the array is not reached.
Tracing the Loop Variable Pass by Pass
Consider a small array of three values, 4, 9, and 12. The source describes the array as having its own slots, with the loop variable as a separate name. Follow what happens on the first pass. The loop reads the value 4 from the first slot and gives it to the loop variable item. The body then assigns 17 to item. At this point item refers to 17, but the first slot of the array still holds 4.
intListis the array, with three slots holding the values 4, 9, and 12- The for-each header gives item one value per pass, starting with 4
- item = 17 rebinds the loop variable only; no array slot is named in this statement
- On the next pass item receives 9 from the array, replacing the earlier assignment
On the second pass the loop takes the value 9 from the second slot and gives it to item. The earlier assignment of 17 is simply replaced. The same thing happens on the third pass with 12. When the loop ends, the array still holds 4, 9, and 12. Nothing in the array was changed, because the loop never gave the array a chance to be written to.
The diagram shows the situation after the body has run on the first pass. The three array cells stand in for the full array, and the same reasoning applies to every slot. Only the loop variable has been reassigned. The array cells keep the values they had before the loop started.
Values Versus the Elements That Hold Them
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.
The two words sound alike in everyday speech, but they point to different things. The element is the slot, the place that stays part of the array. The value is what sits inside that slot right now. A for-each loop is built around values. On each pass it supplies the next value from the array to the loop variable. It does not hand you the element itself. That is why changing the loop variable has no effect on the array: you have received a value, and a value on its own does not point back to the slot it came from.
A useful way to read the loop variable is as a name that is given a value for one pass through the body. When the body executes item = 17, the name item is associated with 17. The array element that supplied the value was never named in that statement, so nothing in the array is reached. The next pass gives item the next value from the array, and the earlier assignment is replaced.
Where a For-each Loop Falls Short
The for-each loop is not always the right tool. The source states that there is no simple way to use it to process only part of an array, and that 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.
| Task | For-each loop | Indexed loop |
|---|---|---|
| Read every value in order | Well suited; the loop is simpler | Works, but needs an index |
| Process only part of the array | Not suitable | Suitable; the index can start or stop anywhere |
| Walk the array in reverse order | Not suitable | Suitable; the index can count down |
| Change array elements | Does not change the array | Suitable; assign to arr[i] |
Choosing between a for-each loop and an indexed loop
Watching an Indexed Loop Write to the Array
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 source gives the form intList[i] = ..., which assigns to the specific slot at position i. The example below is an illustration written for this lesson, not an excerpt from the source. It shows the same three-slot array being filled, this time done correctly.
- The index i names each slot by its position
intList[i] = 17 assigns to the slot itself, not to a temporary name- The loop counts from 0 up to the last position
int[] intList = {4, 9, 12};
for (int item : intList) {
item = 17;
}intList still holds 4, 9, 12; only the loop variable item was assigned
int[] intList = {4, 9, 12};
for (int i = 0; i < intList.length; i++) {
intList[i] = 17;
}intList holds 17, 17, 17; each slot was assigned through its index
Mistakes Beginners Make with For-each Loops
Common mistake Expecting the loop variable to write back into the array
What it looks likefor (int item : intList) { item = 17; }Why it failsThe loop supplies a value to item. The assignment changes the name item, not the slot that supplied the value.
Do this insteadUse an indexed loop and assign to intList[i] when the array must change.
Common mistake Using a for-each loop to process only part of an array
Why it failsA for-each loop visits the values in order from start to finish; the source notes there is no simple way to restrict it to part of an array.
Do this insteadSwitch to an indexed loop whose index starts and stops at the positions you need.
Common mistake Trying to walk a for-each loop backward
Why it failsThe for-each loop cannot walk the elements in reverse order.
Do this insteadUse an indexed loop that counts down from the last position to 0.
Common mistake Treating value and element as the same thing, so that a changed value seems to imply a changed slot
Choosing the Right Loop
An array holds the values 4, 9, and 12. You want to add 1 to every value in the array. Would you use a for-each loop or an indexed loop, and why? Write the loop you would use.
Hints
- Ask whether the goal is to read values or to change the slots that hold them
- Remember that the loop variable receives a value, not a slot
- An indexed loop can assign to
intList[i] directly
Carrying the Value Idea Forward
- 1A for-each loop processes the values in an array, not the elements themselves
- 2Assigning to the loop variable changes only that name, so the array is unchanged
- 3To modify elements, use an indexed loop and assign to the specific slot, such as
intList[i] - 4For-each suits reading every value in order; it is not suitable for partial traversal or reverse order
Key Takeaways
- A for-each loop supplies values from the array to the loop variable, so assigning to the loop variable does not change the array
- An element is the memory location that is part of the array and holds a value; the loop variable receives the value, not the element
- A for-each loop is well suited to reading every value in order but is not suitable for partial traversal or reverse order
- To change array elements, use an indexed loop and assign to the specific slot, such as
intList[i]