Loops: for, while and the enhanced for
Repeating work three ways: the counted for loop, the while loop that stops on a condition, and the enhanced for that walks a whole array.
Repeating work instead of copying it
A loop runs the same block again and again. The counted for loop is the one to reach for first, because all three parts are visible in its header: where the counter starts, how long it may run, and how it changes each time round.
for (int i = 1; i <= 3; i++) reads as: start i at 1, keep going while i is at most 3, and add one to i after each turn. The counter lives only inside the loop, so it cannot be confused with anything outside it.
while, and the enhanced for
A while loop keeps going while a condition holds; the body is responsible for moving that condition along. If nothing inside it changes, the loop never ends — the classic infinite loop, and the reason the example below adds to the counter by hand.
When you only want each item of an array in turn, the enhanced for is shorter and safer: for (String name : crew) gives you each element with no index to get wrong. It is the form to prefer whenever you do not need the position.
Steering a loop from inside
continue skips the rest of this turn and goes on with the next one. break leaves the loop altogether, which is how you stop early once you have what you came for. Both make the loop easier to read than a chain of nested conditions.
The modulus operator % gives the remainder of a division, which is the usual way to spot every second turn: i % 2 == 0 is true for even numbers and false for odd ones.
Tracing a loop
A loop is easiest to understand by making a table. Write the turn number, the value of each variable at the top of the body, and the value after the body. Three rows are usually enough to expose an off-by-one error.
The condition is checked before every turn, including the first. If it is false at the start, the body never runs — which is a feature, not a failure. A do while moves the check to the end and always runs once, and is the right tool when the first attempt must happen. Printing the counter at the top of the body is the same table, produced by the program, and it is often faster than holding the loop in your head.
Loops inside loops
A nested loop runs its inner loop completely for each turn of the outer one. Two loops of three produce nine lines, not six. Keep the counters separate, and give them names that say what they count.
The enhanced for hides the index, which is why it cannot skip an element or walk two arrays in step. When the position matters, use the counted form; when only the value matters, the enhanced form removes a whole class of mistakes.
Choosing the loop
Four shapes cover almost every repetition, and the choice is about how the end is known. A counted for fits when the number of turns comes from a value you already have. A while fits when the end depends on something the loop discovers as it runs, such as when a running total passes a limit. A do while fits when the first attempt has to happen even if the condition is already false. The enhanced for fits when you want every item and never need the position.
Picking the wrong one is not a compile error; it just makes the reader work harder. A while with a counter at the top is a for that has been taken apart, and an index used only to fetch the next item is an enhanced for spelled the long way. Choose the shape that says what you mean, and the boundary conditions become easier to see.
Counting down, and testing the condition first
// Counting down: start high, stop at 1, step by minus one.
for (int i = 3; i >= 1; i--) {
System.out.println(i);
}
// A while loop: the condition is checked before each turn.
int n = 1;
while (n <= 3) {
System.out.println("n is " + n);
n++;
}
// The same work as a counted loop, one line per part.
for (int i = 0; i < 3; i++) {
System.out.println("turn " + i);
}Counting, adding and walking a list
Press Run and follow the output down. Then make the last loop print the even numbers instead, and change the crew array to the names of three people you know.
Three loop mistakes: a condition that never becomes false, an off-by-one boundary (< versus <=), and changing a collection while an enhanced for is walking it. The first hangs until the run times out; the second prints one line too many or too few; the third throws a ConcurrentModificationException.
Try these next
- Print a 5 by 5 grid of
#characters with two nested loops. - Sum the numbers from 1 to 100 with a for loop, then with a while loop, and check that the answers match.
- Print only the multiples of 3 below 20, using
continuerather than an if around the print.
A multiplication table, and two kinds of stop
Press Run and check the grid against the row and column numbers. Then change the table to 6 by 6, and make the second loop add the odd numbers instead of the even ones.
A loop that never ends makes the page wait until the run times out. If a Run seems to hang, check that something inside the loop is changing the value the condition tests.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
In for (int i = 1; i <= 3; i++), what does the middle part do?
