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.
After 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:
Let'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?
continue.
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.
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:
If there are apples in the bowl, then we execute steps 1.1 to 1.4:
- 1.1. Grab an apple
- 1.2. Peel it and cut it into slices
- 1.3. Arrange the apple slices in the pie crust in a pan
- 1.4. Return to step 1.

- 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:
- We evaluate the Boolean expression found in the parentheses after the while keyword.
- 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
- 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:
- The loop body is executed (immediately after the do keyword).
- We evaluate the Boolean expression found in the parentheses after the while keyword.
- If the Boolean expression evaluates to true, then we go to step 1
- If the Boolean expression evaluates to false, then we jump to the first statement after the while loop.
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 — 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.
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:If there are apples in the bowl, then we execute steps 1.1 to 1.4:
- 1.1. Grab an apple
- 1.2. Peel it and cut it into slices
- 1.3. Arrange the apple slices in the pie crust in a pan
- 1.4. Return to step 1.
- Number of slices = 0
As long as the number of slices is < 12, then perform steps 2.1 to 2.3
- 2.1. Cut another slice off the apple
- 2.2. Number of slices++
- 2.3. Return to step 2
If there are apples in the bowl, then we execute steps 1.1 to 1.6:
- 1.1. Grab an apple
- 1.2. Peel it
- 1.3. Number of slices = 0
- 1.4. As long as the number of slices is < 12, then perform steps 1.4.1 to 1.4.3
- 1.4.1. Cut another slice off the apple
- 1.4.2. Number of slices++ 1.4.3. Return to step 1.4
- 1.5. Arrange the apple slices in the pie crust in a pan
- 1.6. Return to step 1.
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.
GO TO FULL VERSION