Command Palette

Search for a command to run...

PHASE 2Beginner ~29 min· topic 5 of 10

Topic 2.5

while and do-while Loops

In one line

A while loop repeats a block as long as a condition stays true, checking the condition before each pass, so it may run zero times. A do-while checks after each pass, so its body always runs at least once.

Think of it like this

Eating soup. While there is soup in the bowl, take a spoonful. You check the bowl before each spoonful, and if it was empty from the start you never pick up the spoon. A do-while is tasting food while cooking: you taste first, then decide whether it needs more salt and another taste.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Loop
A piece of code that repeats.
Iteration
One pass through the loop body.
Loop condition
The boolean test that decides whether the loop runs (again).
Loop variable
A variable whose value changes each iteration and is used in the condition, such as a counter.
Infinite loop
A loop whose condition never becomes false, so it repeats forever (until the program is stopped).
Pre-test loop
A loop that checks its condition before each iteration (while, for).
Post-test loop
A loop that checks its condition after each iteration (do-while).
Sentinel
A special value that signals 'stop', such as 0 at the end of a list of numbers or -1 for 'not found'.

Step by step

01Your first while loop

Three parts make a counting loop work: a starting value (int count = 1), a condition (count <= 3), and a change inside the body (count++). Leave out any one and the loop either never runs or never stops.

Trace it: count is 1, 1 <= 3 is true, print, count becomes 2. Then 2, then 3. Then count is 4, 4 <= 3 is false, the loop ends.

Main.javawhole filejava
int count = 1;
while (count <= 3) {
    System.out.println("Count: " + count);
    count++;
}
System.out.println("Done, count is now " + count);
terminal
$ java Main.java
── expected output ──
Count: 1
Count: 2
Count: 3
Done, count is now 4

02The flow of a pre-test loop

The condition sits at the door. Each time around, Java asks the question again. This is why a while can run zero times: if the answer is no at the start, the body is skipped completely.

The flow of a pre-test loopdiagram
Rendering diagram…

03When you don't know the count: digits of a number

How many digits does 90210 have? You don't know how many times to loop, but you know when to stop: when nothing is left. Each pass removes the last digit with / 10 (integer division, Topic 1.7) and % 10 gives that digit.

This 'peel off the last digit' loop is one of the most common patterns in coding interviews. You'll use it again in Topic 2.10.

Main.javawhole filejava
int n = 90210;
int digits = 0;
int sum = 0;
while (n > 0) {
    sum += n % 10;   // last digit
    n /= 10;         // drop the last digit
    digits++;
}
System.out.println(digits + " digits, sum " + sum);   // 5 digits, sum 12

04do-while: body first, question second

A do-while puts the check at the bottom. The body runs, then the condition decides whether to go round again. Even when the condition is false from the start, the body runs once.

That fits 'do something, then decide whether to repeat' tasks: show a menu and repeat until the user picks Quit, retry an operation until it succeeds, or roll a die until you get a six.

Main.javawhole filejava
int x = 10;
while (x < 5) {
    System.out.println("while body");     // never runs
}
do {
    System.out.println("do-while body");  // runs once
} while (x < 5);
terminal
$ java Main.java
── expected output ──
do-while body
do-while: body first, question seconddiagram
Rendering diagram…

05Scope: what the condition can see

The do body is a block, and variables declared in a block die at its closing brace (Phase 3 covers scope in depth). The while (...) at the bottom is outside that block, so it can't see them.

Declare the variable before the do if the condition needs it.

Main.javawhole filejava
int i = 0;
do {
    int next = i + 1;
    i = next;
} while (next < 5);   // error: cannot find symbol: variable next

// Fixed
int j = 0;
int next2;
do {
    next2 = j + 1;
    j = next2;
} while (next2 < 5);

06Infinite loops: deliberate and accidental

Accidental: forgetting the count++, changing the wrong variable, or a stray semicolon (while (count <= 3); loops forever on an empty body). The program hangs and uses a full CPU core. Stop it with Ctrl+C.

Deliberate: while (true) with a break or return inside, for loops whose exit point is in the middle (Topic 2.8). Servers and game loops are built like this.

The compiler checks constant conditions. Code after a while (true) with no break can never run, so it is an unreachable statement error. That rule keeps you from writing cleanup code that silently never happens.

terminal
$ javac Main.java
── expected output ──
Main.java:6: error: unreachable statement
System.out.println("after");
^
1 error

07Under the hood: a jump back

Bytecode has no loop instruction. A loop is a conditional jump that exits, plus a goto that jumps back. The javap listing below is a counting loop: instruction 6 leaves the loop when i > n, instruction 16 jumps back to the test at 4.

When a loop runs many thousands of times, the JIT compiler notices (it counts back-edges, the jumps back to the top) and compiles the method to machine code, even switching the running loop over mid-iteration. That's on-stack replacement (OSR), and it's why a quick timing of a loop's first few runs says little about its real speed.

terminal
$ javap -c Main
── expected output ──
static int sum(int);
Code:
0: iconst_0
1: istore_1
2: iconst_1
3: istore_2
4: iload_2
5: iload_0
6: if_icmpgt 19
9: iload_1
10: iload_2
11: iadd
12: istore_1
13: iinc 2, 1
16: goto 4
19: iload_1
20: ireturn

Try it yourself

  1. 1

    Trace before you run

    In 'The Collatz sequence', change n to 7. On paper, write the sequence until you reach 1. Then run it and compare (it takes 16 steps and climbs to 52).

  2. 2

    Make it infinite, then fix it

    In 'Counting with while', delete count++. Run it, watch Count: 1 scroll forever, and stop it (Ctrl+C in a terminal, or the stop button in the browser runner). Put the line back.

  3. 3

    while vs do-while

    In 'do-while runs at least once', change the do-while to a while with the same condition. Predict whether anything prints, then run.

Code & diagrams

Counting with while New tab
Sign in to run this example in your browser.

Expected output

Count: 1
Count: 2
Count: 3
After the loop, count = 4
A while loop can run zero times
Digits, reversal and sum New tab

Reversed is 1209, not 01209: an int has no leading zeros.

Sign in to run this example in your browser.

Expected output

Number: 90210
Digits: 5
Sum of digits: 12
Reversed: 1209
The Collatz sequence: loop until a condition New tab

Nobody has proved this loop ends for every starting number (the Collatz conjecture), but it has for every number ever tried.

Sign in to run this example in your browser.

Expected output

6 -> 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
Reached 1 in 8 steps
do-while runs at least once New tab
Sign in to run this example in your browser.

Expected output

do-while body ran with x = 10
Attempt 1: failed
Attempt 2: failed
Attempt 3: success
Compound interest: how many years to double? New tab

The 'rule of 72' predicts 72 / 7 = about 10.3 years; the loop gives the exact whole-year answer.

Sign in to run this example in your browser.

Expected output

Doubled after 11 years: 2104.85

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Use a body variable in the do-while condition

Declare next inside the do block and test it in while (next < 5).

Main.javawhole filejava
public class Main {
    public static void main(String[] args) {
        int i = 0;
        do {
            int next = i + 1;
            i = next;
        } while (next < 5);
    }
}
terminal
$ javac Main.java
── what you'll see ──
Main.java:7: error: cannot find symbol
} while (next < 5);
^
symbol: variable next
location: class Main
1 error

Break #2

Write code after an endless loop

Put a println after while (true) { ... } with no break inside.

Main.javawhole filejava
public class Main {
    public static void main(String[] args) {
        while (true) {
            System.out.println("x");
        }
        System.out.println("after");
    }
}
terminal
$ javac Main.java
── what you'll see ──
Main.java:6: error: unreachable statement
System.out.println("after");
^
1 error

Break #3

A semicolon after while

Write while (count <= 3); followed by the block.

terminal
$ java Main.java
── what you'll see ──
(no output; the program hangs and one CPU core goes to 100%)

Myth vs fact

Myth

A while loop always runs at least once.

Fact

That's do-while. A while checks first and may run zero times.

Myth

while (true) is always a bug.

Fact

It's the standard shape for loops that exit from the middle with break or return, like menus, servers and retry loops.

Myth

Loops are slow in Java because it's interpreted.

Fact

Hot loops are JIT-compiled to machine code (even mid-run, via on-stack replacement), and the JIT unrolls and vectorises simple ones.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    JLS 14.22 defines 'can complete normally' rules: while (true) without a reachable break cannot complete normally, so following statements are unreachable; while (false) makes its body unreachable. Note the asymmetry with if (false), which is allowed so you can write debug flags.

  • ▸

    The JIT inserts safepoint polls at loop back-edges so the GC can pause threads. Counted int loops may have the poll removed for speed, which historically caused long time-to-safepoint pauses; since JDK 10, loop strip mining splits long counted loops into chunks so polls stay frequent without slowing the inner loop.

  • ▸

    A busy-wait like while (!flag) {} on a plain (non-volatile) field may never see another thread's update: the JIT is allowed to hoist the read out of the loop. That's a memory-model issue, covered in the concurrency phase. Use volatile, an AtomicBoolean, or proper blocking instead.

  • ▸

    do-while compiles to a body followed by a conditional jump back, which is the natural shape for the CPU; javac places a while test at the top, and the JIT usually rotates it to the bottom (loop inversion) so each iteration costs one jump.

Remember this

  1. 1

    while (condition) { body } checks the condition; if it's true it runs the body, then checks again, and so on. As soon as the check is false, the loop ends and the program continues after it. If the condition is false the first time, the body runs zero times.

  2. 2

    do { body } while (condition); runs the body first and checks afterwards, so the body runs at least once. Note the semicolon after the closing bracket. A variable declared inside the do body can't be used in its condition, because the body's block has already ended.

  3. 3

    Every loop needs something inside it that eventually makes the condition false: a counter that increases, input that runs out, a value that converges. Without that, you get an infinite loop. while (true) is a deliberate infinite loop that you leave with break (Topic 2.8) or return.

  4. 4

    Use while when you don't know in advance how many times to repeat: until a number reaches 1, until the digits run out, until a search finds its target. When you know the count (do it 10 times, visit every array index), the for loop in Topic 2.6 is clearer.

  5. 5

    The compiler knows constant conditions. while (false) { ... } is an unreachable statement error, and code after a while (true) loop with no break is also unreachable, so it's rejected.

  6. 6

    In bytecode a while is a conditional jump at the top (or bottom) plus a goto back. A loop that runs many times gets compiled to machine code by the JIT, and long-running loops are even swapped to compiled code mid-run (on-stack replacement).

Explain it without notes

01

What is the difference between while and do-while? Give a situation suited to each.

02

What three things does a counting while loop need, and what goes wrong if each is missing?

03

Why is code after while (true) { ... } with no break a compile error?

04

When would you choose a while loop over a for loop?

Practice

01

Using a while loop, print the powers of 2 that are less than 100, on one line separated by spaces.

02

Using a while loop, check whether 12321 is a palindrome number (reads the same backwards).

03

Using a do-while loop, print the numbers from 5 down to 1, then Lift off!.

Trade-offs

  • ↔

    while keeps the loop condition clear when the count is unknown, but the start and update are scattered across lines, making off-by-one and forgotten-update bugs easier than in a for.

  • ↔

    do-while is the right tool for 'at least once', but it is rare in real code; many teams prefer while (true) with a break, which puts the exit test wherever it naturally belongs.

Done when you can

  • Done when you can write a while loop with a start, a condition and an update, and trace it on paper.

  • Done when you can explain when a do-while is the right choice.

  • Done when you can write the 'peel off the last digit' loop from memory.

  • Done when you can recognise and fix an infinite loop and an unreachable-statement error.

  • Done when you can explain that a loop is a conditional jump plus a goto in bytecode, and what OSR is.