Loops: for, while, do-while
Repeating work, the anatomy of a for loop, and how to choose between the three forms.
Finished reading?
Mark this session so you can track where you are.
Repeating work, the anatomy of a for loop, and how to choose between the three forms.
Finished reading?
Mark this session so you can track where you are.
So far, every line in your program runs once, top to bottom. But real programs are full of work that needs doing again and again: print ten lines, add up a hundred numbers, keep asking until the answer is right. This session is about telling the computer to repeat itself, without you having to repeat yourself.
for loop and say the exact order they run in.for, while, and do-while for a given problem.break to leave a loop early and continue to skip one round.if that is willing to run its body more than once.Suppose you want to print the numbers 1, 2, 3, 4, 5 on separate lines. With only the tools you have so far, you would write five almost-identical lines.
public class Main { public static void main(String[] args) { System.out.println(1); System.out.println(2); System.out.println(3); System.out.println(4); System.out.println(5); }}1 2 3 4 5
It works, but look at how brittle it is. To print up to 100 you would write 100 lines. If you decide to print each number doubled, you have to edit every single line and hope you do not miss one. The number that changes (1, then 2, then 3) is buried inside otherwise identical code. There is no single place that says “keep going until you reach the end”.
A loop separates the work that stays the same (print a number) from the thing that changes (which number). You write the body once, and the loop runs it as many times as you ask.
The for loop is built for exactly this: when you know, or can compute, how many times to repeat. Its header has three parts separated by semicolons, and then a body in braces. Here is the same counting task as a single loop.
public class Main { public static void main(String[] args) { for (int i = 1; i <= 5; i = i + 1) { System.out.println(i); } }}1 2 3 4 5
The three parts in the header each have a job. Read them left to right:
int i = 1. Runs once, before anything else. It sets up a variable, the loop counter, that tracks where we are.i <= 5. Checked before every round. While it is true, the loop keeps going. The moment it is false, the loop stops.i = i + 1. Runs after each round, to move the counter along so we eventually reach the end.And then the body in braces is the work itself: System.out.println(i). The single most important thing to get right is the order these run in. It is not top to bottom. It goes like this:
init once. Now i is 1.condition. If false, stop now. If true, carry on.body.update.Notice that init happens exactly once, and from then on it is condition, body, update, condition, body, update, and so on, until the condition finally fails. The check always comes before the body, so if the condition is false on the very first try, the body never runs at all.
Words only go so far. Press Run on the program below and step through it. Keep your eye on i and sum. You will literally see i climb, the condition get rechecked each time, and sum grow.
public class Main { public static void main(String[] args) { int sum = 0; for (int i = 1; i <= 5; i = i + 1) { sum = sum + i; } System.out.println("The sum of 1 to 5 is " + sum); }}The sum of 1 to 5 is 15
Trace it by hand and confirm what the visualizer shows. The body runs five times. With i equal to 1, 2, 3, 4, then 5, the running total becomes 1, then 3, then 6, then 10, then 15. When i reaches 6 the condition i <= 5 is false, so the loop stops and we print The sum of 1 to 5 is 15.
i = i + 1 is perfectly correct and clear. Java also offers i += 1 (add and store back) and the even shorter i++ (increment by one), which you will see everywhere in loop headers. They all do the same thing here. We will use the long form in these notes so the meaning stays obvious, but recognize i++ when you meet it.Sometimes you do not know in advance how many rounds you need. You just know the rule for stopping. Maybe you keep halving a number until it reaches 1, or keep going until a total crosses some line. For that, the while loop reads more naturally. It is the barest loop: just a condition and a body.
A whileloop says “as long as this condition is true, run the body”. There is no built-in init or update slot, so you set things up before the loop and change them inside the body yourself. Here is a countdown.
public class Main { public static void main(String[] args) { int n = 5; while (n > 0) { System.out.println("T minus " + n); n = n - 1; } System.out.println("Liftoff"); }}T minus 5 T minus 4 T minus 3 T minus 2 T minus 1 Liftoff
Step through it. We start with n at 5. Each round prints the current n and then lowers it by one. After printing for 5, 4, 3, 2, and 1, the variable n becomes 0, the condition n > 0 is now false, and the loop ends. Then Liftoff prints once. That last line is outside the loop, so it runs a single time, after the loop is done.
n = n - 1. Without it, n would stay at 5 forever, the condition n > 0 would stay true forever, and the loop would never stop. That is an infinite loop. Every while loop needs something inside its body that nudges the condition toward false. If you ever write a loop and it seems to hang, this is the first thing to check.Both loops above check the condition before the first round, so it is possible for the body to run zero times. The do-while loop flips that order. It runs the body first, then checks the condition at the bottom. This guarantees the body runs at least once, no matter what the condition says.
The shape is do { ... } while (condition);. Note the semicolon at the very end, which the other loops do not have. Watch how the body runs even though the condition is false from the start.
public class Main { public static void main(String[] args) { int n = 100; do { System.out.println("The body ran with n = " + n); n = n + 1; } while (n < 5); System.out.println("Done"); }}The body ran with n = 100 Done
Trace it. The condition is n < 5, and n starts at 100, so the condition is false immediately. Yet the body still runs once, printing The body ran with n = 100, because do-while checks the condition only after the body. Then n becomes 101, the condition 101 < 5 is false, and the loop exits. A plain while loop with the same condition would have printed nothing at all.
A
whileloop may run its body zero times. Ado-whileloop always runs its body at least once, because it checks the condition at the end.
do-while fits. We have not met keyboard input yet, so we cannot run that example here. It is coming in Scanner and console applications.while (...).Two keywords let you steer a loop from inside its body. break leaves the loop entirely, right now, skipping everything that is left. continue skips only the rest of the current round and jumps ahead to the next one (in a for loop, it still runs the update first, then rechecks the condition).
The program below walks i from 1 toward 10. It skips even numbers with continue, and it stops completely when it reaches 7 with break. Run it and watch the flow jump.
public class Main { public static void main(String[] args) { for (int i = 1; i <= 10; i = i + 1) { if (i == 7) { break; } if (i % 2 == 0) { continue; } System.out.println(i); } System.out.println("Loop finished"); }}1 3 5 Loop finished
Trace it carefully, because both keywords are in play. Recall that i % 2 is the remainder when i is divided by 2, so i % 2 == 0 is true exactly when i is even.
i = 1: not 7, and odd, so it prints 1.i = 2: even, so continue skips the print and goes to the next round.i = 3: prints 3. i = 4: skipped. i = 5: prints 5. i = 6: skipped.i = 7: break fires and the loop ends at once.So the output is 1, 3, 5, then Loop finished. The numbers 7 through 10 are never reached, because break abandoned the whole loop, not just one round. That is the key difference: continue means “skip the rest of this round”, while break means “I am done with this loop completely”.
Almost every famous beginner program is really just a loop with a small idea inside it. Here are four you will be asked to write again and again. Read each one, then press Run and step through to watch the value build up.
The factorial of 5 (written 5!) is 1 * 2 * 3 * 4 * 5. The pattern is: start a running product at 1, then loop from 1 to n multiplying it in each time.
public class Main { public static void main(String[] args) { int n = 5; int fact = 1; for (int i = 1; i <= n; i = i + 1) { fact = fact * i; } System.out.println("Factorial: " + fact); }}Factorial: 120
Watch fact climb: 1, then 2, 6, 24, and finally 120. Each pass folds one more number into the running product. That “running total” shape, a variable outside the loop that the loop keeps updating, is one you will use constantly.
The Fibonacci sequence starts 0, 1 and then every term is the sum of the two before it: 0 1 1 2 3 5 8 .... We keep two variables for the last two terms and roll them forward.
public class Main { public static void main(String[] args) { int n = 10; int first = 0; int second = 1; System.out.print(first + " " + second + " "); for (int i = 3; i <= n; i = i + 1) { int next = first + second; System.out.print(next + " "); first = second; second = next; } }}0 1 1 2 3 5 8 13 21 34
The trick is the three lines at the end of the loop: compute the next term, then slide first and second forward so they always hold the latest two. Print the first ten terms and you get 0 1 1 2 3 5 8 13 21 34.
To turn 1234 into 4321, peel off the last digit with % 10, build the reversed number, then drop that digit with / 10, and repeat until nothing is left. A while loop fits perfectly, because you do not know in advance how many digits there are.
public class Main { public static void main(String[] args) { int num = 1234; int reversed = 0; while (num != 0) { int digit = num % 10; reversed = reversed * 10 + digit; num = num / 10; } System.out.println("Reversed: " + reversed); }}Reversed: 4321
Each pass takes the last digit (num % 10) and pushes it onto the growing reversed by multiplying the old value by ten and adding the digit. Meanwhile num / 10 chops the digit off the original. When num reaches 0, every digit has moved across, reversed.
A prime number is divisible only by 1 and itself. To check, try dividing by every number from 2 up to just below the number; if any divides evenly (remainder 0), it is not prime. A boolean flag remembers the verdict.
public class Main { public static void main(String[] args) { int number = 29; boolean isPrime = true; for (int i = 2; i < number; i = i + 1) { if (number % i == 0) { isPrime = false; break; } } if (isPrime && number > 1) { System.out.println(number + " is prime"); } else { System.out.println(number + " is not prime"); } }}29 is prime
Notice the break: the moment we find one divisor, we know the answer is “not prime”, so there is no point checking further. We flip the flag to false and leave the loop immediately. For 29, nothing divides it, the flag stays true, and we print that it is prime.
Loops introduce two mistakes that catch almost everyone at first. Knowing their names makes them easy to spot.
This is running one time too many or one time too few, almost always because of a wrong boundary: < where you meant <=, or starting at 1 when you meant 0. Suppose you want to print 1 through 5. The loop for (int i = 1; i < 5; i = i + 1) stops at 4, because i < 5 is false when i is 5. You wanted i <= 5. The fix is always to ask: on the last value I care about, is the condition still true?
public class Main { public static void main(String[] args) { System.out.println("Wrong (i < 5):"); for (int i = 1; i < 5; i = i + 1) { System.out.println(i); } System.out.println("Right (i <= 5):"); for (int i = 1; i <= 5; i = i + 1) { System.out.println(i); } }}Wrong (i < 5): 1 2 3 4 Right (i <= 5): 1 2 3 4 5
false. The usual causes are forgetting to update the counter, updating it the wrong way (counting up when the condition needs it to go down), or a condition that can never be reached. In the visualizer a runaway loop is stopped for you, but a real program would simply hang. Before you run any loop, check that something inside it genuinely pushes the condition toward false.Try each one yourself first, then open the answer.
for loop and say which one runs only once.for (int i = 0; i < 3; i = i + 1) { System.out.println(i); }while loop has the condition x < 10, and x starts at 50. How many times does the body run? Now answer the same question for a do-while loop with the same condition and start.break does and what continue does.int i = 1; while (i <= 10) { System.out.println(i); }Take these away. They continue exactly what we just did.
for loop that prints only the even numbers from 2 to 20, inclusive. Do it two ways: once by stepping the counter up by 2 each round, and once by stepping up by 1 and using continue to skip the odd numbers. Confirm both print the same lines.while loop, compute and print the factorial of 5, that is 5 * 4 * 3 * 2 * 1. Start a result variable at 1 and a counter at 5, multiply the result by the counter each round, and count down until the counter reaches 1. The answer should be 120.break. Which number does it stop at, and what is the last number it prints before stopping?< or <=.