In many situations, we may not know exactly how many times a loop will need to repeat and a for loop is not the best choice. For example, the number of iterations might depend on the user entering some special value to exit the loop. In this case, a condition-controlled loop, like a while loop is ideal.
The best way to think of a while loop is like an if statement that repeats its code block (also called a loop body) as long as its condition evaluates to true. Consider this code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import java.util.Scanner; public class WhileLoop { public static void main( String[] args ) { Scanner input = new Scanner( System.in ); int sum = 0; int newValue; // Prompt the user to enter a series of integers, 0 to stop System.out.println( "Enter a series of integers, 0 to quit:" ); newValue = input.nextInt(); // Keep reading until the user enters a 0 while ( newValue != 0 ) { sum += newValue; newValue = input.nextInt(); } System.out.println( "The sum of integers entered is: " + sum ); } } |
Enter a series of integers, 0 to quit:
3
1
5
0
The sum of integers entered is: 9
The code above reads very naturally: “While the newValue entered by the user is not 0, add it to our sum, get the next newValue, and begin the next iteration. When 0 is entered, and the loop ends, display the sum of integers entered.”
Can you see how this differs from the for loop example last time? Here we don’t know how many integers the user will enter before the loop is terminated. This program is more flexible because it supports any number of positive integers being entered, including none.
Like the for loop, the while loop is a pre-test loop because the loop continuation condition is checked at the start of the while loop before the body is executed. If the condition evaluates to false when the while loop first starts (e.g., imagine if the first newValue entered on line 11 was 0 right away), then the body of the loop will not execute at all. In other words, the body of the while loop may iterate 0 or more times, depending on the loop continuation condition.
The break Statement
Sometimes it’s necessary to test some condition in the middle of a loop and terminate early. Java supports the break statement for this purpose. If a break is encountered inside a loop it terminates the current loop immediately (it does not finish running the loop body). Code execution continues with the first line of code following the loop.
Here’s our count down program again, but when countDown equals 3 the loop is stopped early.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class BreakLoop { public static void main( String[] args ) { int countDown = 5; while ( countDown > 0 ) { System.out.print( countDown + " " ); if ( countDown == 3) { break; } countDown--; } System.out.println( "\nCount down aborted at " + countDown ); } } |
5 4 3
Count down aborted at 3
The break and continue statements can be powerful tools, but use them sparingly because they can lead to code that is poorly designed and harder to understand.
How to “break” Nested Loops
Like the continue statement, the break statement only applies to the loop in which it resides. This raises an interesting challenge if we have nested loops and some condition in the inner-most loop requires us to terminate all nested loops, not just the inner one.
To solve this problem, we use a break statement, as usual, to terminate the inner loop and a boolean variable as a special “flag” to terminate any outer loops. Here’s a sample solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class NestedBreak { public static void main( String[] args ) { for ( int i = 0; i < 5; i++ ) { // We'll use this variable as a flag to terminate the outer loop boolean keepGoing = true; for ( int j = 0; j < 5; j++ ) { if ( j == 3 ) { System.out.println( "Breaking out of all loops!" ); // Use flag to cause outer for loop to terminate too keepGoing = false; break; } System.out.printf( "i=%d, j=%d\n", i, j); } if ( keepGoing == false ) { break; } } } } |
i=0, j=0
i=0, j=1
i=0, j=2
Breaking out of all loops!
On line 5 we define a boolean keepGoing variable to control the termination of the outer loop. Note that because this variable is defined within the outer for loop its scope is any code within that loop, including the inner for loop. This variable is checked just after the inner loop terminates at line 16. This technique can work well for any level of nesting.
You Try!
-
- Convert the following for loop to a while loop:
123for (int x = 10; x > 0; x--) {System.out.println(x + " second(s) to go.");} - Convert the following while loop to a for loop:
12345int count = 0;while (count < 20) {System.out.printf("count is %d.\n", count);count++;}
- Convert the following for loop to a while loop: