Traditional for Loops with Arrays
A for-each loop is an alternative form of the for loop that makes it easier to visit every value in an array or collection.
Predicting What a Loop Prints
Programs often need to do the same thing to every item in a collection. If you have an array of names and want to print each one, you can write a loop that visits every value and prints it. This article introduces the for-each loop, a shorter form of the for loop built for exactly this job. Before reading the explanation, study the code below and decide what appears on the screen and in what order.
- The array holds three Strings, each stored in a fixed order
- The loop header names a variable called name that takes one value per pass
- The body prints whatever value name currently holds
What do you think happens?
How many lines does this loop print, and what does each line contain?
Reveal answer
Three lines: Ada, then Grace, then Linus, in that order.
The body runs once for each value in the array, and each run prints the value that name currently holds. The loop visits the array from its first value to its last, so the output follows the stored order.
If your prediction matched, good. If it did not, ask which assumption was off. Did you expect the loop to run more or fewer times than the array has values, or did you expect the printed text to differ from the stored values? Keep that question in mind as you read the explanation.
Reading the For-Each Header
The general form of a for-each loop is written as a type, then a variable name, then a colon, then the array or collection to be walked through. The body in curly braces is repeated once for each element. In the example above, the type is String, the variable is name, and the array is namelist.
A helpful way to read the header aloud is: for each String, called name, in the array namelist, do the following. The colon is read as the word in or from. Read this way, the header describes a traversal. The loop visits the array in turn, and at each visit a single value is made available under the name you chose.
Stepping Through the Array Value by Value
Trace the loop from the earlier example one pass at a time. Notice that each pass hands the body one value, and that the loop ends only when the values run out. The decision that continues or stops the loop checks whether values remain, not whether a counter has reached a number.
- 1Pass 1: the loop checks that a value remains, then sets name to Ada. The body prints Ada.
- 2Pass 2: the loop checks that a value remains, then sets name to Grace. The body prints Grace.
- 3Pass 3: the loop checks that a value remains, then sets name to Linus. The body prints Linus.
- 4Check: no values remain, so the loop ends and nothing else runs.
How a Traditional Loop Reaches Each Element
A traditional for loop usually keeps an integer counter and uses it to fetch elements. It counts from zero up to the array length and fetches each item by its position. The for-each loop does not do this. No array index appears in a for-each loop, so when position information is needed, a traditional for loop is the right tool.
- The counter i starts at 0 and is the position of the value being fetched
- The condition stops the loop once i reaches the array length
- namelist[i] fetches the element stored at position i
The diagram shows the counter moving from index 0 to the last index. Each index selects one specific element. The traditional loop must declare the counter, state where it starts, state when it stops, and fetch each element by its position. The for-each loop needs only the header and the body.
Comparing the Two Loops Side by Side
| Feature | for-each loop | Traditional for loop |
|---|---|---|
| What the loop variable holds | One value from the array | An integer counter, used as an index |
| Index appears in the loop | No | Yes |
| Position information available | No, use a traditional loop instead | Yes |
| Setup needed | Only the header and the body | Counter declaration, start, stop, and fetch by position |
Comparing how each loop reaches array elements
Finding Where Output Diverges
When a for-each loop's output differs from what you expected, the failure is usually in one of three places: the header, the body, or the data in the array. Check them in that order. The loop faithfully reports whatever the array holds, so the output can only differ from your expectation for one of these reasons.
Common mistake Assuming the loop variable is an index
What it looks likePrinting name expecting 0, 1, 2 instead of the stored names
Why it failsThe loop control variable represents one of the values in the array, not its position.
Do this insteadIf you need the position, use a traditional for loop with an integer counter.
Common mistake Mismatched element type in the header
What it looks likeString[] names with the header for (int name : names)Why it failsThe type after the opening parenthesis must match the element type of the array.
Do this insteadMake the header type match the element type, here String.
Common mistake Traversing the wrong array
What it looks likeHeader names the array namelist when the intended array was another one
Why it failsThe array named after the colon is the one the loop walks through.
Do this insteadConfirm the name after the colon is the array you meant to traverse.
Common mistake Expecting different text from the stored values
Why it failsThe body prints the value it receives, so the printed text comes straight from the array contents.
Do this insteadInspect the array contents to see what is actually stored.
Suppose a loop over a String array prints a wrong name on its second line. Work through the three places in order. The header is correct, since the type is String and the array after the colon is the intended one. The body prints name unchanged, so it is not the cause. The array contents are the likely source: the second stored value is the wrong name. Fixing the stored data corrects the output, and the loop itself needed no change.
Predict and Locate Practice
Given the array String[] cities = {"Lagos", "Accra", "Nairobi"} and the loop for (String city : cities) { System.out.println(city.toUpperCase()); }, predict the output before reading further. Then say which line would be the first to differ if the array instead held the value Acra in place of Accra.
Hints
- Decide how many passes the loop makes before counting the output lines
- Remember that the loop variable holds a stored value, not its position
- Compare each printed line with the stored value that produced it
Key Takeaways
- A for-each loop is an alternative form of the for loop that makes it easier to visit every value in an array or collection.
- The header for (Type variable : array) reads as for each value in the array, do the following, and the loop variable holds one value per pass, not an index.
- A traditional for loop keeps an integer counter and fetches elements by position, so use it when position information is needed.
- When output differs from expectation, check the header, then the body, then the array contents, in that order.