4.3 while, for, and Iteration
Prerequisites: Boolean conditions, scope, and assignment
Estimated time: 35 minutes
You are ready to continue when: You can choose a loop for a condition, count, or sequence of elements and explain its execution order
while: First Check, Then Execute
int delivered = 0;
while (delivered < 10) {
delivered++;
System.out.println("Delivered component " + delivered);
}Each iteration follows this sequence:
Condition check
├─ false: Exit loop
└─ true: Execute loop body → Return to condition checkTo ensure the correctness of a loop, at least the following questions must be answered:
- What is the initial state?
- How does each iteration progress?
- When does the termination condition become
false? - Are there any issues with the boundary iterations, such as running one iteration too many or too few?
If the condition is initially false, the loop body will not execute at all.
for: Putting the Counting Structure in One Place
for (int index = 0; index < 10; index++) {
System.out.println(index);
}Execution Order:
Initialization (once)
↓
Condition
├─ false: End
└─ true: Loop Body → Update → Back to ConditionThis explains a detail: A continue targeting a basic for loop runs the update expression, then check the condition; in while, continue directly returns to the condition, so you must ensure the state has advanced.
All three parts of for can be omitted:
for (;;) {
// Explicit infinite loop
}An infinite loop itself is not necessarily an error. Event loops, servers, and consumers run for long periods, but must be designed with paths for cancellation, closure, exception handling, backoff, and resource release. Tutorial exercises often use a maximum number of iterations to avoid uncontrolled behavior.
Half-Open Ranges Reduce Boundary Errors
Array indices typically use [0, length):
int[] scores = {80, 90, 70};
for (int index = 0; index < scores.length; index++) {
System.out.println(index + ": " + scores[index]);
}The initial index includes 0, and the end boundary is excluded length. The last valid index is length - 1.
Reverse traversal:
for (int index = scores.length - 1; index >= 0; index--) {
System.out.println(scores[index]);
}When the array is empty, the initial value is -1, and the condition is immediately false.
Enhanced for: Read Each Element
for (int score : scores) {
System.out.println(score);
}This is suitable for traversal when indexing is not required. The loop variable receives each element's value; reassigning the loop variable does not change the original array of primitive types:
for (int score : scores) {
score = 0;
}
System.out.println(scores[0]); // Still is 80For an array of objects, the loop variable copies the reference value. You can modify the state of the object through the reference, but assigning the loop variable to point to another object does not replace the array element. This topic will be discussed further in the next chapter on collections.
do-while: Execute First, Then Judge
int attempts = 0;
do {
attempts++;
System.out.println("attempt " + attempts);
} while (attempts < 1);The loop body executes at least once. A semicolon must follow the while (...) at the end. It is suitable for processes that involve "reading once first, then deciding whether to continue," but interaction and resource code must still handle input termination, exceptions, and cancellation.
Don't Use Floating-Point Equality to Control the Number of Iterations
double value = 0.0;
while (value != 1.0) {
value += 0.1;
}Binary approximation might skip the exact 1.0, causing the condition to remain true indefinitely. Iterating by count is more reliable:
for (int step = 0; step < 10; step++) {
double value = step / 10.0;
System.out.println(value);
}If the loop is controlled by a physical error threshold, use a domain-defined tolerance and add a maximum number of iterations to avoid relying solely on an approximate condition for termination.
Common Loop Errors
State does not advance:
int count = 0;
while (count < 10) {
System.out.println(count);
// Forgot to update count
}Semicolon creates an empty loop body:
for (int index = 0; index < 10; index++); // Empty statement
{
System.out.println("Execute once only");
}Formatting tools may make the structure more apparent, but in the end, code review and test coverage for 0, 1, and the last iteration beyond the bound are required.
Python and C++ Boundary
Python for iterates over iterable objects, range(10) provides 0 to 9; it is not the C-style three-part for loop. Python also supports loop else: it runs when for exhausts its elements normally or a while condition becomes false. It does not run when break, return, or an exception exits the loop.
C++ has similar while, do-while, three-part, and range-based for loops, but conditions allow contextual conversion to bool, and the boundaries for types, iterator invalidation, and undefined behavior differ, so they cannot be considered identical.
Professional Quick Reference
| Situation | Preferred Structure |
|---|---|
| Known Count or Index | for |
| Continuation Based on State | while |
| At Least One Execution | do-while |
| Read Each Element Once | Enhanced for |
| Long-Running Service | Explicit Cancellation, Backoff, Exceptions, and Resource Closure |
| Numeric Iteration | Error Conditions + Maximum Iteration Count |
Before Moving On
Trace a for loop over an empty array, a one-element array, and a three-element array. Mark the initialization, condition check, body, and update in order. Then explain where continue falls in relation to for and while, and why approximate numerical loops still require the maximum iteration count. Being able to draw these paths means the loop boundaries are truly checkable.
Next, we’ll stop when a target is found and skip an iteration when an item is invalid.
→ Next step: break, continue, and labels
Specification: JLS §14.12–14.14: while, do, and for.