Loops enable programs to execute code multiple times.

The while Loop

First, we’ll take a look at the while loop, also known as the while statement. This is what a while loop looks like:

while (condition) {
    // code goes here
}

As we can see, a while loop looks very similar to an if statement. The only difference is the keyword if is replaced with while. In fact, in terms of functionality they are quite similar, too. Both an if statement and while loop will start by checking the condition, and if it’s true, the code in the body will be executed. If it’s false, the body will be skipped. The difference between them is that once a while loop reaches the end, it will go back up and recheck the condition. If the condition is still true, the body will be executed again. This process repeats until the condition is false, at which point the body will be skipped and the program continues as normal.

An Infinite Loop

An infinite loop is a loop that never stops repeating because the condition is always true. For example:

public class InfiniteLoop {
    public static void main(String[] args) {
        while (5 < 10) {
            System.out.println("Hi!");
        }
    }
}

The expression 5 < 10 will always be true so the loop will keep repeating. This means the print statement on line 4 will be executed over and over again, flooding the Run window with “Hi!” (the program can be stopped by clicking the Stop button ):

Much Hi!

How fast does it loop? As fast as your processor is willing to go. Printing to the console isn’t the fastest operation, relatively speaking, so it’ll probably take a few seconds to print 1 million strings, for instance. In other situations, a loop may repeat up to billions of times in mere milliseconds. It largely depends on the code being executed and the hardware it’s running on.

But the main question is: how do we devise a condition that is true initially but becomes false at some point in the future? The most common way is by using a variable as a counter.

A Loop Counter

The following program declares a variable called i and increases it by 1 every time the loop repeats.

public static void main(String[] args) {
    int i = 0;

    while (i < 5) {
        System.out.println("Hi!");
        i = i + 1;
    }
}
[Run]
Hi!
Hi!
Hi!
Hi!
Hi!

These are the steps the program takes:

  1. Line 2 declares an int variable i and sets it to 0.
  2. Line 4 is where the while loop starts. First, the condition is checked. It reads i < 5, and since i is 0, it checks 0 < 5. This is true, therefore the body of the loop executes.
  3. On line 5, the string “Hi!” is printed once. This is the first “Hi!” you see in the sample run.
  4. On line 6, i is incremented (increased) by 1. The right side is worked out first, and the result is stored back in i, overwriting the previous value. In essence:
    1. i = i + 1
    2. i = 0 + 1
    3. i = 1
  5. Line 7 is the closing curly bracket ( } ), which marks the end of the loop.
  6. The program goes back up to the condition on line 4 and checks it again. Since i = 1, the condition is 1 < 5, which is true, so the loop runs a second time.
  7. Line 5 prints “Hi!” again.
  8. Line 6 increments i again (i = 1 + 1, therefore i = 2)
  9. Line 4 checks the condition again. Since i = 2, it reads 2 < 5, which is true.
  10. Line 5 prints “Hi!” a third time.
  11. Line 6 increments i a third time. (i = 2 + 1, therefore i = 3)
  12. Line 4 checks i < 5 (3 < 5). It’s true.
  13. Line 5 prints “Hi!” again.
  14. Line 6 increments i to 4 (i = 3 + 1 → i = 4).
  15. Line 4 checks i < 5 (4 < 5). It’s true.
  16. Line 5 prints “Hi!” again.
  17. Line 6 increments i to 5 (i = 4 + 1 → i = 5).
  18. Line 4 checks i < 5 (5 < 5). It’s false, therefore the loop is skipped over.
  19. The program ends and we’re left with five “Hi!” in the console.

Hopefully you can see the pattern. Succinctly, the steps are:

  1. Check the condition.
  2. print “Hi!”.
  3. Increment i.
  4. [Go to step 1].

i is a very common name for a variable used in loops, especially when used to control the number of iterations (repetitions). j and k are also used when i is being used for something else. But remember that you can use any name you see fit, as short or long as you want. You could call the variable counter instead of i, for example.

Counting Numbers

Instead of printing “Hi!”, we can print i itself to see its value increasing:

public static void main(String[] args) {
    int i = 0;

    while (i < 5) {
        System.out.println(i);
        i = i + 1;
    }
}
[Run]
0
1
2
3
4

On line 5, instead of printing Hi!, it is printing variable i itself. As we can see from the output, i starts at 0 and ends at 4. What if we wanted to print a different range of numbers, say, 15 to 30? What changes would we need to make to the loop to achieve this? We would just need to change the starting value of i (line 2) as well as the condition (line 4), which determines i‘s end value, as shown in the following program:

public static void main(String[] args) {
    int i = 15;

    while (i < 31) {
        System.out.println(i);
        i = i + 1;
    }
}
[Run]
15
16
17
18
...
27
28
29
30

As we can see, i starts at 15 (line 2) and the loop ends when i is 31 (line 4). Every iteration, line 5 prints i and line 6 increments i, resulting in the output above.

Note
If you don’t like the fact that the condition reads 31 but stops at 30, you can rewrite it as i <= 30 and that would give the same result.

There’s a shorter way we can write line 6, and that is i += 1. This is just shorthand for i = i + 1. Both will add i + 1 and store the result back in i. Increasing a variable by 1 is such a common requirement that Java also has the increment operator ( ++ ) for this very purpose. For example, we could replace line 6 with i++. Again, this means “increase i by 1”. There’s also the decrement operator ( -- ) which decreases a variable by 1 (e.g. i-- ). We can also increase i by larger steps by adding a larger number e.g. i = i + 3 or i += 3. This just increases i by 3 every time it’s executed. This shorthand can also be done for subtraction, multiplication, and division by using the relevant operator, for example:

  • i = i – 5 is the same as i -= 5 (Take 5 away from i)
  • i = i * 2 is the same as i *= 2 (Multiply i by 2)
  • i = i / 3 is the same as i /= 3 (Divide i by 3)
  • i = i * i is the same as i *= i (Square i)
  • i = i + 1 is the same as i += 1 is the same as i++ (Add 1 to i)
  • i = i – 1 is the same as i -= 1 is the same as i-- (Subtract 1 from i)

In each example, the value of i will be changed. As an aside, you may be under the impression that a line like i – 5 decreases i by 5, but it doesn’t. It merely calculates the result of i – 5 but doesn’t do anything with that result so it is effectively a useless statement. If you want to overwrite i with the result then you have to write i = i – 5.

Let’s look at another example, where the loop counts down instead of up and also moves in steps of 3.

public static void main(String[] args) {
    int i = 21;

    while (i >= 0) {
        System.out.println(i);
        i -= 3;
    }
}
[Run]
21
18
15
12
9
6
3
0

Let’s run through it:

  1. Line 2 starts i at 21.
  2. Line 4 checks i >= 0 (21 >= 0), which is true.
  3. Line 5 prints i (21).
  4. Line 6 decreases i by 3 so i is now 18.
  5. Line 4 checks i >= 0 (18 >= 0), which is true.
  6. Line 5 prints i (18).
  7. Line 6 decreases i by 3 so i is now 15.
  8. Lines 4, 5, and 6 keep repeating until i is -3, at which point the condition i >= 0 (-3 >= 0) is false, so the loop stops and the program ends.

Mid-chapter Exercise

As an exercise, see if you can figure out the output of the programs below without running them beforehand. The solutions follow.

Note
As a beginner, if you ever get stuck trying to work out the behaviour of a particular loop, try going through it manually on a piece of paper, step by step, from beginning to end. Keep track of any variables, like i, by writing down its value as it changes. Write down the output as that would appear, too. You should start to see a pattern emerging.

Program A

public static void main(String[] args) {
    int i = 5;

    while (i < 10) {
        System.out.println(i);
        i++;
    }
}

Program B

public static void main(String[] args) {
    int i = 4;

    while (i < 20) {
        System.out.println(i);
        i += 2;
    }
}

Program C

public static void main(String[] args) {
    int i = 100;

    while (i >= 84) {
        System.out.println(i);
        i -= 4;
    }
}

Program D

public static void main(String[] args) {
    int i = 3;

    while (i <= 200) {
        System.out.println(i);
        i *= 2;
    }
}

Solutions

Program AProgram BProgram CProgram D
5
6
7
8
9
4
6
8
10
12
14
16
18
100
96
92
88
84
3
6
12
24
48
96
192

The for Loop

The for loop basically serves as a more compact version of the while loop. The process of declaring a variable, checking it in a condition, and then incrementing it is so common, that the for loop was designed as an all-in-one solution. The for loop looks like this:

while (initialisation; condition; incrementation) {
    // code goes here
}

Unlike the while loop, whose parentheses only contain the condition, the for loop’s parentheses is split into three sections by semicolons. First comes the variable initialisation, where a variable is given a value. In the middle is the condition. The third part is the variable incrementation, where the variable is modified. A for loop will always start with the initialisation. Afterwards, it will follow the same repeating pattern, which is:

  1. condition
  2. body
  3. incrementation

For example, here is what the first program looks like with a for loop instead of a while loop:

public static void main(String[] args) {
    for (int i = 0; i < 5; i++) {
        System.out.println("Hi!");
    }
}
[Run]
Hi!
Hi!
Hi!
Hi!
Hi!

This is the sequence of steps the program takes:

  1. Line 2 is the start of the for loop. First is the initialisation, where an int variable i is declared and initialised to 0.
  2. The condition is checked. i < 5 means 0 < 5, which is true.
  3. The body is executed. In this case, “Hi!” is printed one time.
  4. The program goes back up to the top, to the incrementation. The code i++ increases i by 1 so i is now 1.
  5. Steps 2 through 4 are simply repeated over and over again with i increasing by 1 each time. When i eventually reaches 5, the condition will be false. Then the program will skip over the loop and the program will end.

The do-while Loop

The do-while loop works the same as the while loop except the condition is checked at the end instead of the beginning. The do-while loop looks like this:

do {
    code goes here
} while (condition);

Here is the same example where i goes from 0 to 5 using the do-while loop:

public class DoWhileLoop {
    public static void main(String[] args) {
        int i = 0;

        do {
            System.out.println(i);
            i++;
        } while (i < 5);
    }
}
[Run]
0
1
2
3
4
  1. Line 3 declares variable i that is set to 0.
  2. Line 5 is the start of the do-while loop. There is no condition so the program simply enters the loop.
  3. Line 6 prints i (0). Line 7 increases i by 1. Line 8 evaluates the condition i < 5 (1 < 5). It’s true so the program goes back to the top of the loop.
  4. Step 3 repeats four more times with increasing values of i. When i reaches 5, the condition is false and the program ends.

break and continue

The break and continue keywords disrupt the normal flow of a loop. The break keyword will stop the loop prematurely and the program will carry on as normal (it causes the program to break out of the loop). The continue keyword causes the loop to skip the current iteration and continue with the next one. Let’s see the break keyword in action first:

public static void main(String[] args) {
    System.out.println("START");

    for (int i = 0; i < 10; i++) {

        if (i == 3) {
            break;
        }

        System.out.println(i);
    }

    System.out.println("END");
}
[Run]
START
0
1
2
END

The program starts on line 2 by printing the word “START”. Line 4 begins a normal for loop that starts with i at 0 (initialisation) and ends when i is 10 (condition). Line 10 prints i every iteration like normal. However, the loop also contains an if statement on lines 6-8 containing the break keyword. As can be seen from the output, when i is 0, 1, and 2, the condition i == 3 on line 6 is false and line 10 prints i as normal. But when i reaches 3, the condition i == 3 is true and the program hits line 7 which causes the program to break out of the loop. Line 13 prints “END” and the program ends.

Let’s now run the same program but replace break with continue:

public static void main(String[] args) {
    System.out.println("START");

    for (int i = 0; i < 10; i++) {

        if (i == 3) {
            continue;
        }

        System.out.println(i);
    }

    System.out.println("END");
}
[Run]
START
0
1
2
4
5
6
7
8
9
END

The program starts exactly the same way as the previous one. Except this time, when i is 3, the continue keyword will cause the loop to continue to the next iteration. In other words, the program will go back up to the top of the loop and continue as normal. This means that line 10 doesn’t get a chance to print i when it’s 3, because the loop moved on before it could. We can see this from the output—all numbers are printed except 3. Finally, when i is 10 the loop stops as per the condition, line 13 prints “END”, and the program ends.

Roll a Die

Let’s look at a practical example of loops. The following program simulates a dice roll by generating a random number from 1 to 6 and displaying the result. A do-while loop is used for the purpose of repeating the program. The user decides if they want the program to repeat by entering either “y” (for yes) or “n” (for no).

import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;

public class DiceRoll {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String again;

        do {
            int roll = ThreadLocalRandom.current().nextInt(1, 7);
            System.out.printf("You rolled a %d\n", roll);
            System.out.print("Roll again? y/n: ");
            again = sc.next();
        } while (again.equals("y"));
    }
}

Line 6 instantiates a Scanner (sc). Line 7 declares a String variable called again. This variable will hold the user’s response for repeating the program. Line 9 begins the do-while loop. Line 10 generates a random number from 1 to 6 and stores it in variable roll. Line 11 prints “You rolled a roll” (e.g. if roll is 3 then it would print “You rolled a 3”). Line 12 asks the user if they would like to roll again and to answer “y” or “n”. Line 13 obtains the user’s response into variable again. Line 14 is the end of the do-while loop and the condition is checked to see if again equals “y”. If true, the loop will repeat, starting at line 10 (or line 9 if there were code directly after the opening bracket). The program goes through the same process, with line 10 generating another random number and so on. Eventually, when the user enters “n” on one of the iterations, the condition will be false so the loop stops and the program subsequently ends. Note that the user can technically enter anything other than “y” to end the program.

[Run]
You rolled a 5
Roll again? y/n: y
You rolled a 2
Roll again? y/n: y
You rolled a 1
Roll again? y/n: y
You rolled a 3
Roll again? y/n: y
You rolled a 5
Roll again? y/n: n

Roll the Dice

Rolling one die at a time is good but rolling multiple dice is even better. To do that, we can ask the user how many dice they would like to roll and use a loop to roll each one. This loop can go inside the do-while loop.

import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;

public class RollTheDice {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String again;

        do {
            System.out.print("\nEnter number of dice to roll: ");
            int diceCount = sc.nextInt();

            for (int i = 0; i < diceCount; i++) {
                int roll = ThreadLocalRandom.current().nextInt(1, 7);
                System.out.printf("Die %d rolled a %d\n", i + 1, roll);
            }

            System.out.print("Roll again? y/n: ");
            again = sc.next();
        } while (again.equals("y"));

        System.out.println("\nExiting...");
    }
}

As we can see, lines 9-20 are the do-while loop and lines 13-16 are a for loop. Since the for loop is inside the do-while loop, the for loop is the inner loop and the do-while loop is the outer loop. Let’s go through how it works. On line 10, the program asks the user to enter the number of dice to roll. Line 11 obtains this number and stores it in a variable called diceCount (other possible names include numDice and numberOfDice). Line 13 begins the for loop. Variable i starts at 0, increases by 1 every iteration, and stops when i < diceCount, ensuring the loop repeats the number of times specified by the user. Every iteration, line 14 generates a random number and stores it in variable roll. Line 15 prints out this number in a thematic way e.g. “Die 1 rolled a 3.” Notice that i is used for the die number; specifically, i + 1. This is because the loop starts with i at 0, as is often the case with loops, but we want the die numbering to start at 1, therefore a plus 1 offset gives us the correct numbering. For example, in the sample run, we can see the dice are numbered 1, 2, 3, 4, 5, and not 0, 1, 2, 3, 4. Once all dice are rolled, the loop ends and lines 18-19 ask the user if they want to roll again and the user’s response is store in variable again. The outer loop will repeat if again equals “y”. In such a case, the program goes back up to line 9 and the process repeats, with line 10 asking the user to enter the number of dice to roll and so forth. When the user decides they’ve had enough and enters “n”, line 22 prints “Exiting…” just before the program ends.

[Run]
Enter number of dice to roll: 2
Die 1 rolled a 4
Die 2 rolled a 2
Roll again? y/n: y
Enter number of dice to roll: 5
Die 1 rolled a 4
Die 2 rolled a 3
Die 3 rolled a 6
Die 4 rolled a 4
Die 5 rolled a 1
Roll again? y/n: n
Exiting…

We may want to know what the dice add up to but would rather the program tell us. Let’s have the program calculate and display the sum of all dice:

int sum = 0;
for (int i = 0; i < diceCount; i++) {
    int roll = ThreadLocalRandom.current().nextInt(1, 7);
    System.out.printf("- Die %d rolled a %d\n", i + 1, roll);
    sum += roll;
}
System.out.printf("Total: %d\n", sum);

Above the for loop, line 1 declares variable sum, which starts at 0. This will hold the dice total by the time all the dice are “rolled”. For each roll, line 5 adds the roll to sum. Remember, the += operator means to add the two variables together and store the result in the left variable. For example, if a 3 were rolled, then sum + roll would be 0 + 3 = 3. Therefore, sum would be 3. If a 5 were rolled next, then sum + roll would be 3 + 5 = 8. Therefore, sum would be 8. Subsequent rolls would be added to sum. Once the loop finishes, then line 7 prints sum.

[Run]
Enter number of dice to roll: 4
Die 1 rolled a 4
Die 2 rolled a 2
Die 3 rolled a 5
Die 4 rolled a 6
Total: 17
Roll again? y/n: n
Exiting…

Leave a Reply

Your email address will not be published. Required fields are marked *