The while statement

Published in the Java Developer group

Introduction

Our very first programs were a sequence of instructions that are executed one after another. No forks. This includes HelloWorld, which displays a greeting. It includes arithmetic calculations. The while statement - 1After our first programs, we learned how to branch, i.e. how to make a program perform different actions depending on specific conditions. Here's code for controlling a central heating and air conditioning system:

if (tempRoom>tempComfort)
    airConditionerOn();
if (tempRoom<tempComfort)
    heaterOn();
Take the next step. In everyday life, we often perform uniform repetitive actions, for example, peeling apples for a pie. This fascinating process can be described as:
  1. If there are apples in the bowl, then we execute steps 1.1 to 1.4:

    1. 1.1. Grab an apple
    2. 1.2. Peel it and cut it into slices
    3. 1.3. Arrange the apple slices in the pie crust in a pan
    4. 1.4. Return to step 1.
The while statement - 2Let's say you have ten apples, two hands, and one knife. In real life, you sequentially peel the entire dozen, following the same algorithm for each apple. But how do we make a program do a repetitive action for each apple?
  • We tie ourselves to the number of apples, but if we don't have enough of them, then some of the commands would be executed without a "payload" (and we might cut ourselves while trying to peel a nonexistent apple).
  • If there are more apples than commands to peel, then some of the apples would be left unpeeled.
  • Such code is hard to read. It has lots of repetitions and is difficult to modify.

Loops are statements that allow actions to be performed repeatedly

Java's while loop will work well in our case. This construct puts multiple actions into a concise and understandable structure. Using a while loop, an apple-slicing algorithm for a pie might look like this in Java:

while (numberOfApplesInBowl > 0) {
    apple = bowl.grabNextApple();
    arrangeInPie(apple.peel().slice());
    numberOfApplesInBow--; // "--" is the decrement operator, which reduces the number of apples by one
}
System.out.println("The apples for the pie have been processed.");

Command syntax

The first variant of the while statement is like this:

while (Boolean expression) {
	// Loop body — the statement(s) that are repeatedly executed
}
Here's a step-by-step explanation of what happens when this code is executed:
  1. We evaluate the Boolean expression found in the parentheses after the while keyword.
  2. If the Boolean expression evaluates to true, then the statements in the loop body are executed. After the last statement in the loop body is executed, then we go to step 1
  3. If the Boolean expression evaluates to false, then we jump to the first statement after the while loop.

Loop with a precondition

Because we always evaluate the Boolean expression (the condition for entering the loop) before we execute the loop body, this form of the while loop is often called a loop with a precondition. Let's build a table of the first ten powers of a number:

public static void main(String[] args) {
    int base = 3; // The number that will be exponentiated
    int result = 1; // The result of exponentiation
    int exponent = 1; // The initial exponent
    while (exponent <= 10) { // The condition for entering the loop
        result = result * base;
        System.out.println(number + " raised to the power of " + exponent + " = " + result);
        exponent++;
    }
}
Console output:

3 raised to the power of 1 = 3
3 raised to the power of 2 = 9
3 raised to the power of 3 = 27
3 raised to the power of 4 = 81
3 raised to the power of 5 = 243
3 raised to the power of 6 = 729
3 raised to the power of 7 = 2187
3 raised to the power of 8 = 6561
3 raised to the power of 9 = 19683
3 raised to the power of 10 = 59049
Process finished with exit code 0

Loop with a postcondition

Here's the second variant of this loop:

do {
    // Loop body — the statement(s) that are repeatedly executed
} while (Boolean expression);
Here's an explanation of what happens when this code is executed:
  1. The loop body is executed (immediately after the do keyword).
  2. We evaluate the Boolean expression found in the parentheses after the while keyword.
  3. If the Boolean expression evaluates to true, then we go to step 1
  4. If the Boolean expression evaluates to false, then we jump to the first statement after the while loop.
The two main differences from the previous loop are: 1) the loop body is executed at least once and 2) the Boolean expression is evaluated after the loop body is executed. Accordingly, this kind of while loop is called a loop with a postcondition. This time we'll display a table of powers of a number that do not exceed 10000:

public static void main(String[] args) {
    int base = 3; // The number that will be exponentiated
    int result = number; // The result of exponentiation
    int exponent = 1; // The initial exponent
    do {
        System.out.println(number + " raised to the power of " + exponent + " = " + result);
        exponent++;
        result = result * number;
    } while (result < 10000); // The condition for exiting the loop
Console output:

3 raised to the power of 1 = 3
3 raised to the power of 2 = 9
3 raised to the power of 3 = 27
3 raised to the power of 4 = 81
3 raised to the power of 5 = 243
3 raised to the power of 6 = 729
3 raised to the power of 7 = 2187
3 raised to the power of 8 = 6561
Process finished with exit code 0
Pay attention to the changes in the code. Compare this with the loop with a precondition.

Interesting facts about working with loops

Branching statements within the loop body

There are two statements that affect execution within a loop: break (which we'll discuss in greater detail in the next chapter) and continue.
  • continue — skips execution of the rest of the loop body in the current iteration and jumps to the evaluation of the while statement's Boolean expression. If the expression evaluates to true, then the loop continues.
  • break — immediately terminates execution of the current iteration and transfers control to the first statement after the loop. Thus, this statement ends execution of the current loop. We'll consider it in more detail in the next article.
Recall our fruit example. If we're unsure of the quality of the apples, we could change the code using a continue statement:

while (numberOfApplesInBowl > 0) {
    apple = bowl.grabNextApple();
    numberOfApplesInBow--; // "--" is the decrement operator, which reduces the number of apples by one
    if (apple.isBad()) { // This method returns true for rotten apples
        apple.throwInGarbage();
        continue; // Continue the loop. Jump to evaluation of numberOfApplesInBowl > 0
    }
    arrangeInPie(apple.peel().slice());
}
The continue statement is often used when statements in the loop body need to be executed if a certain condition is satisfied. For example, we may want to perform actions when a hardware sensor is triggered (otherwise, simply continue the loop in which we take sensor readings) or we may want to calculate an expression only on certain iterations of a loop. An example of the latter case can be seen in our use of a while loop to calculate of the sum of cubes of natural numbers whose square is less than the number of numbers. Confused? Check out the following code:

public static void main(String[] args) {
    int sum = 0;  // Total amount
    int i = 0;  // Initial number in the series
    int count = 20;  // Number of numbers
    while (i <= count) {
        i++;  // Get the next number — "i++" is equivalent to "i = i + 1"
        if (i * i <= count)  // If the square of the number is less than
            continue;  // the number of numbers, then we won't calculate the sum
                            // Jump to the next number in the loop
        sum += i * i * i;  // Otherwise, we calculate the sum of the cubes of numbers
    }  // "sum += i * i * i" is notation that is equivalent to "sum = sum + i * i * i"
    System.out.println(sum);  // Print the result
}

Infinite loop

These branching statements are used most often in infinite loops. We call a loop infinite if the Boolean condition for exiting the loop is never satisfied. In code, it looks something like this:

while (true) {
    // Loop body 
}
In this case, a break statement helps us exit the loop. This type of loop is suitable when waiting for external conditions determined outside the body of the loop. For example, in operating systems or games (exiting the loop means exiting the game). Or when using algorithms that try, with each iteration of a loop, to improve some result, but limit the number of iterations based on elapsed time or the occurrence of an external event (e.g. checkers, chess, or weather forecasting). Remember that under normal conditions infinite loops are not desirable. To demonstrate, let's return to exponentiation:

public static void main(String[] args) {
    int base = 3; // The number that will be exponentiated
    int result = 1; // The result of exponentiation
    int exponent = 1; // The initial exponent
    while (true) {
        result = result * number;
        System.out.println(number + " raised to the power of " + exponent + " = " + result);
        exponent++;
        if (exponent > 10)
            break; // Exit the loop
    }
}
Console output:

3 raised to the power of 1 = 3
3 raised to the power of 2 = 9
3 raised to the power of 3 = 27
3 raised to the power of 4 = 81
3 raised to the power of 5 = 243
3 raised to the power of 6 = 729
3 raised to the power of 7 = 2187
3 raised to the power of 8 = 6561
3 raised to the power of 9 = 19683
3 raised to the power of 10 = 59049
Process finished with exit code 0

Nested loops

And now we come to our final topic on loops. Recall that apple pie (I hope you're not hungry at the moment) and our apple-peeling loop:
  1. If there are apples in the bowl, then we execute steps 1.1 to 1.4:

    1. 1.1. Grab an apple
    2. 1.2. Peel it and cut it into slices
    3. 1.3. Arrange the apple slices in the pie crust in a pan
    4. 1.4. Return to step 1.
Let's describe slicing process in more detail:
  1. Number of slices = 0
  2. As long as the number of slices is < 12, then perform steps 2.1 to 2.3

    1. 2.1. Cut another slice off the apple
    2. 2.2. Number of slices++
    3. 2.3. Return to step 2
And we'll add this to our pie-making algorithm:
  1. If there are apples in the bowl, then we execute steps 1.1 to 1.6:

    1. 1.1. Grab an apple
    2. 1.2. Peel it
    3. 1.3. Number of slices = 0
    4. 1.4. As long as the number of slices is < 12, then perform steps 1.4.1 to 1.4.3
      1. 1.4.1. Cut another slice off the apple
      2. 1.4.2. Number of slices++
      3. 1.4.3. Return to step 1.4
    5. 1.5. Arrange the apple slices in the pie crust in a pan
    6. 1.6. Return to step 1.
Now we have a loop within a loop. Constructs like this are very common. As a final example, let's build one of the multiplication tables we learned to love in elementary school.

 public static void main(String[] args) {
    // Print the second factors in a row
    System.out.println("    2  3  4  5  6  7  8  9"); 
    int i = 2;  // Assign the first factor to the variable
    while (i < 10) {  // First loop: execute as long as the first factor is less than 10
        System.out.print(i + " | ");  // Print the first factor at the beginning of the line
        int j = 2;  // The starting value of the second factor
        while (j <10) { // Second loop: execute as long as the second factor is less than 10
            int product = i * j;  // Calculate the product of the factors
            if (product <10)  // If the product is a single digit, then we print two spaces after the product
                System.out.print(product + "  ");
            else  // Otherwise, print the product and one space after it
                System.out.print(product + " ");
            j++;  // Increment the second factor by one
        }  // Go to the beginning of the second loop, i.e. "while (j < 10)"
        System.out.println();  // Move to the next line on the console
        i++;  // Increment the first factor by one
    } // Go to the beginning of the first loop, i.e. "while (i < 10)"
}
Console output:

     2  3  4  5  6  7  8  9
2 | 4 6 8 10 12 14 16 18
3 | 6 9 12 15 18 21 24 27
4 | 8 12 16 20 24 28 32 36
5 | 10 15 20 25 30 35 40 45
6 | 12 18 24 30 36 42 48 54
7 | 14 21 28 35 42 49 56 63
8 | 16 24 32 40 48 56 64 72
9 | 18 27 36 45 54 63 72 81
Process finished with exit code 0
Loops (in particular, the while statement) are one of the fundamental building blocks of software. By solving tasks on CodeGym, you'll learn all the different kinds of loops, come to understand their intricacies, and gain practical skills in using them.
Comments (3)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Siyanda Dlamini Level 7, Durban, South Africa
13 March 2022
This explanation is priceless.
Le Phan Level 14, Véry, France
21 December 2021
There are two miss-typing errors in the text. First, there is no "base" variable. It should be change to "number" instead. As in the context following, number variable was used very often.

public static void main(String[] args) {
    int base = 3; // The number that will be exponentiated
    int result = 1; // The result of exponentiation
    int exponent = 1; // The initial exponent
    while (exponent <= 10) { // The condition for entering the loop
        result = result * base;
        System.out.println(number + " raised to the power of " + exponent + " = " + result);
        exponent++;
    }
}
Next, in the context of "The continue statement is often used when statements in the loop body ... An example of the latter case ... calculate of the sum of cubes of natural numbers whose square is less than the number of numbers", it should be notice that their square is not less than the number of numbers as shown in the code.
Andrei Level 41
4 November 2020
Berry nice!