Java Flow Control: while and do-while Statements

Introduction

Conditional statements and loops are a very important tool in programming. There aren't many things we could do with code that can only execute line-by-line.

That's what "flow control" means - guiding the execution of our program, instead of letting it execute line-by-line regardless of any internal or external factors. Every programming language supports some form of flow control, if not explicitly via ifs and fors or similar statements - then it implicitly gives us the tools to create such constructs, i.e. low-level programming languages usually achieve that affect with a lot of go-to commands.

Loops were a concept used long before computer programming was even a thing, but the first person to use a software loop was Ada Lovelace, commonly known by her maiden name - Byron, while calculating Bernoulli numbers, back in the 19th century.

In Java, there are several ways to control the flow of the code:

while

A loop is a set of instructions that are repeatedly executed until some condition is met, or alternatively as long as a condition is true. The while loop in Java works on the latter principle, it repeats a block of code as long as the condition evaluates to true:

while(condition) {
    // Block of code to be executed
}

When Java encounters a while loop it does the following:

  • Is the condition true?
    • Yes -> execute the block of code. Check the condition again.
    • No -> don't execute the block of code. Don't check the condition again.

This means that if we had a statement like while(true), the block of code would execute indefinitely (or at least, try to). This is called an infinite loop and is to be avoided unless we have a way of breaking out of the loop - typically with a break statement.

The condition can be any type of Boolean expression, the same as with if statements.

Since while checks the condition before executing any code, it is possible that the block of code within the while loop is never executed if the condition was false at the beginning.

This is different from a for loop, which typically executes a set number of times. while loops, on the other hand, are often used to execute an unknown number of times.

Here's an example of a while loop that sums up all the digits of an int.

int n = 123;
int sumOfDigits = 0;

while(n > 0) {
    int lastDigit = n % 10; // Retrieves the last digit of n via the modulus operator
    n = n / 10; // "Removes" the last digit from n via division

    sumOfDigits += lastDigit; // Adds the current digit to the sum
}

System.out.println(sumOfDigits);

The execution of this code works in the following way:

  • The while condition is checked, n is 123 and sumOfDigits is 0. Is n > 0 equal to true? Yes -> execute the code in the loop.
  • The while condition is checked, n is 12 and sumOfDigits is 3. Is n > 0 equal to true? Yes -> execute the code in the loop.
  • The while condition is checked, n is 1 and sumOfDigits is 5. Is n > 0 equal to true? Yes -> execute the code in the loop.
  • The while condition is checked, n is 0 and sumOfDigits is 6. Is n > 0 equal to true? No -> execute the first line after the loop, in our case print out the result.

After executing the while loop 3 times, a value of 6 is printed to the console.

The body of the while loop can be empty, and sometimes developers like to write shorthand while loops when possible. Additionally, the same rule of shortening if and else statements applies to while. So a single-line while loop can be re-written without the brackets, like this:

// This...
while(i < j) {
    System.out.println("i " + i++ + "    j " + j--);
}

// ...becomes this:
while(i < j)
    System.out.println("i " + i++ + "    j " + j--);

Also notice that the variables used in the checked condition can be changed either within the while loops code block or within the checked condition itself:

while(++i < --j)
    System.out.println("i "  + i + "   j " + j);

Both of these result in the same output:

i 1   j 9
i 2   j 8
i 3   j 7
i 4   j 6

However, they may reduce readability and should be avoided if they do.

do-while

This loop does essentially the same thing as while, but it guarantees that the block of code will be executed at least once.

This is because, unlike in while, the code is executed before the condition is checked. So even if we start off with a false condition, it'll execute the code and then check if it should do it again:

int i = 0;

// This will print once
do {
    System.out.println(i);
    i--;
} while(i > 0);

The output of the code is:

0

After the code reaches while(i > 0), it stops the iterations.

For example, one use-case for do-while is to ask the user if they want to try doing something again in case it fails.

do {
    // Try to connect to a server, access a resource, etc...
    String status = connectToServer();

    // Ask user whether they want to try again
    String userInput = getUserInput("Connection status is " + status + ". Want to try again?");
} while(userInput == "yes");

This can be done with a regular while loop, but it's more readable and intuitive this way.

Conclusion

Flow control in code is essential for absolutely every application. Statements that alter the flow of code are fundamental building blocks and every aspiring developer should be completely in control/aware of how they work.

while and do-while loops are good for executing a block of code an unknown number of times, where a condition is checked every time the code block re-runs.