More loops
The "while-true" loop we've been using is very handy when the program has to repeat a functionality until the user provides certain input.
Next, we'll come to know a few other ways to implement loops.
While Loop with a Condition
So far we have been using a loop with the boolean true
in its parenthesis, meaning the loop continues forever (or until the loop is ended with the break
command ).
Actually, the parenthesis of a loop can contain a conditional expression, or a condition, just like the parenthesis of an if
statement. The true
value can be replaced with an expression, which is evaluated as the program is executed. The expression is defined the same way as the condition of a conditional statement.
The following code prints the numbers 1,2,...,5. When the value of the variable number
is more than 5, the while
-condition evaluates to false and the execution of the loop ends for good.
int number = 1;
while (number < 6) {
System.out.println(number);
number++;
}
The code above can be read "As long as the value of the variable number is less than 6, print the value of the variable number and increase the value of the variable number by one".
Above, the value of the variable number
is increased by one every time the loop body is executed.
For Loop
Above, we learned how a while
loop with a condition can be used to go through numbers in a certain interval.
The structure of this kind of loop is the following.
int i = 0;
while (i < 10) {
System.out.println(i);
i++;
}
The above loop can be split into three parts. First we introduce the variable i
, used to count the number of times the loop has been executed so far, and set its value to 0: int i = 0;
. This is followed by the definition of the loop — the loop's condition is i < 10
so the loop is executed as long as the value of the variable i
is less than 10. The loop body contains the functionality to be executed System.out.println(i);
, which is followed by increasing the value of the variable i++
. The command i++
is shorthand for i = i + 1
.
The same can be achieved with a for
loop like so.
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
A for
loop contains four parts: (1) introducing the variable for counting the number of executions; (2) the condition of the loop; (3) increasing (or decreasing or changing) the value of the counter variable; and (4) the functionality to be executed.
for (*introducing a variable*; *condition*; *increasing the counter*) {
// Functionality to be executed
}
Loop execution is shown below step by step.
The example above prints the numbers from zero to four.
The interval can also be defined using variables — the example below uses variables start
and end
to define the interval of numbers the loop goes through.
int start = 3;
int end = 7;
for (int i = start; i < end; i++) {
System.out.println(i);
}
We will continue practicing loops in the following exercises. You can use either a while
loop with a condition, or a for
loop.
On Stopping a Loop Execution
A loop does not stop executing immediately when its condition evaluates to true. A loop's condition is evaluated at the start of a loop, meaning when (1) the loop starts for the first time or (2) the execution of a previous iteration of the loop body has just finished.
Let's look at the following loop.
int number = 1;
while (number != 2) {
System.out.println(number);
number = 2;
System.out.println(number);
number = 1;
}
It prints the following:
1 2 1 2 1 2 ...
Even though number
equals 2 at one point, the loop runs forever.
The condition of a loop is evaluated when the execution of a loop starts and when the execution of the loop body has reached the closing curly bracket. If the condition evaluates to true
, execution continues from the top of the loop body. If the condition evaluates to false
, execution continues from the first statement following the loop.
This also applies to for
loops. In the example below, it would be incorrect to assume that the loop execution ends when i
equals 100. However, it doesn't.
for (int i = 0; i != 100; i++) {
System.out.println(i);
i = 100;
System.out.println(i);
i = 0;
}
The loop above never stops executing.
Repeating Functionality
One common subproblem type is to "do something a certain amount of times". What's common to all these programs is repetition. Some functionality is done repeatedly, and a counter variable is used to keep track of the repetitions.
The following program calculates the product 4*3 somewhat clumsily, i.e., as the sum 3 + 3 + 3 + 3:
int result = 0;
int i = 0;
while (true) {
result += 3; // shorthand for result = result + 3
i++; // shorthand for i = i + 1
if (i == 4) {
break;
}
}
System.out.println(result);
The same functionality can be achieved with the following code.
int result = 0;
int i = 0;
while (i < 4) {
result += 3; // shorthand for result = result + 3
i++; // shorthand for i = i + 1
}
System.out.println(result);
Or by using a for loop as seen in the following.
int result = 0;
for (int i = 0; i < 4; i++) {
result += 3;
}
System.out.println(result);
The program execution using a while loop is visualized below.
On the Structure of Programs Using Loops
In the previous examples, we have concentrated on cases where the loop is executed a predetermined number of times. The number of repetitions can be based on user input — in these cases, the for loop is quite handy.
In programs where the loop body has to be executed until the user gives certain input, the for loop is not too great. In these cases, the while-true loop we practiced earlier works well.
Let's take a look at a somewhat more complex program that reads integers from the user. The program handles negative numbers as invalid, and zero stops the loop. When the user enters zero, the program prints the sum of valid numbers, the number of valid numbers and the number of invalid numbers.
A possible solution is detailed below. However, the style of the example is not ideal.
Scanner reader = new Scanner(System.in);
System.out.print("Write numbers, negative numbers are invalid: ");
int sum = 0;
int validNumbers = 0;
int invalidNumbers = 0;
while (true) {
int input = scanner.nextInt();
if (input == 0) {
System.out.println("Sum of valid numbers: " + sum);
System.out.println("Valid numbers: " + validNumbers);
System.out.println("Invalid numbers: " + invalidNumbers);
break;
}
if (input < 0) {
invalidNumbers++;
continue;
}
sum += input;
validNumbers++;
}
In the code above, the computation executed after the loop has ended has been implemented inside of the loop. This approach is not recommended as it can easily lead to very complex program structure. If something else — for example, reading more input — is to be done when the loop ends, it could also easily end up being placed inside of the loop. As more and more functionality is needed, the program becomes increasingly harder to read.
Let's stick to the following loop structure:
Scanner reader = new Scanner(System.in);
// Create variables needed for the loop
while (true) {
// read input
// end the loop -- break
// check for invalid input -- continue
// handle valid input
}
// functionality to execute after the loop ends
In other words, the program structure is cleaner if the things to be done after the loop ends are placed outside of it.
Scanner reader = new Scanner(System.in);
System.out.print("Write numbers, negative numbers are invalid: ");
int sum = 0;
int validNumbers = 0;
int invalidNumbers = 0;
while (true) {
int input = Integer.valueOf(reader.nextLine());
if (input == 0) {
break;
}
if (input < 0) {
invalidNumbers++;
continue;
}
sum += input;
validNumbers++;
}
System.out.println("Sum of valid numbers: " + sum);
System.out.println("Valid numbers: " + validNumbers);
System.out.println("Invalid numbers: " + invalidNumbers);