Repeating code with loops
Here we will learn how to repeatedly execute portions of our code in a controlled and precise way by looking at different types of loops in Java. These include while
loops, do while
loops, and for
loops. We will also learn the most appropriate situations to use the different types of loops.
It would be completely reasonable to ask what loops have to do with programming, but they are exactly what the name implies. They are a way of repeating the same part of the code more than once, or looping over the same part of code although potentially for a different outcome each time.
This can simply mean doing the same thing until the code being looped over (iterated) prompts the loop to end. It could be a predetermined number of iterations as specified by the loop code itself. It might be until a predetermined situation or condition is met. Or it could be a combination of more than one of these things. Along with if
, else
, and switch
, loops are part of the Java control flow statements.
We will look at all the major types of loops that Java offers us to control our code and we will use some of them to implement a working mini-app to make sure we understand them completely. Let's look at the first and simplest loop type in Java called the while
loop.
While loops
Java while
loops have the simplest syntax. Think back to the if
statements for a moment. We could put virtually any combination of operators and variables in the conditional expression of the if
statement. If the expression evaluated to true
then the code in the body of the if
block is executed. With the while
loop we also put an expression that can evaluate to true
or false
. Take a look at this code:
int x = 10; while(x > 0){ x--; // x decreases by one each pass through the loop }
What happens here is this: outside of the while
loop an int
named x
is declared and initialized to 10
. Then, the while
loop begins. Its condition is x > 0
. So, the while
loop will continue looping through the code in its body until the condition evaluates to false
. So the previous code will execute 10 times.
On the first pass x = 10
then 9
then 8
, and so on. But once x
is equal to 0
, it is of course no longer greater than 0
, the program will exit the loop and continue with the first line of code after the while
loop.
Just like an if
statement, it is possible that the while
loop will not execute even once. Take a look at this:
int x = 10; while(x > 10){ // more code here. // but it will never run unless x is greater than 10. }
Moreover, there is no limit to the complexity of the conditional expression or the amount of code that can go into the loop body:
int newMessages = 3; int unreadMessages = 0; while(newMessages > 0 || unreadMessages > 0){ // Display next message // etc. } // continue here when newMessages and unreadMessages equal 0
The previous while
loop would continue to execute until both newMessages
and unreadMessages
were equal to or less than zero. As the condition uses logical OR operator ||
either one of those conditions being true
will cause the while
loop to continue executing.
It is worth noting that once the body of the loop has been entered, it will always complete, even if the expression evaluates to false
part way through, as it is not tested again until the code tries to start another pass. For example:
int x = 1; while(x > 0){ x--; // x is now 0 so the condition is false // But this line still runs // and this one // and me! }
The previous loop body will execute exactly once. We can also set a while
loop that will run forever; unsurprisingly called an infinite loop. Here is one:
int x = 0; while(true){ x++; // I am going to get mighty big! }
Breaking out of a loop
We might use an infinite loop like this so that we can decide when to exit the loop from within its body. We would do this by using the break
keyword when we are ready to leave the loop body. Like this:
int x = 0; while(true){ x++; //I am going to get mighty big! break; // No you're not haha. // code doesn't reach here }
And you might have been able to guess that we can combine any of the decision-making tools like if
, else
, and switch
within our while
loops and all the rest of the loops we will look at in a minute. For example:
int x = 0; int tooBig = 10; while(true){ x++; // I am going to get mighty big! if(x == tooBig){ break; } // No you're not haha. // code reaches here only until x = 10 }
It would be simple to go on for many more pages demonstrating the versatility of while
loops, but at some point we want to get back to doing some real programming. So, here is one last concept combined with while
loops.
Continue
The continue
keyword acts in a similar way to break
, up to a point. The continue
keyword will break out of the loop body but will also check the condition expression afterwards so the loop could run again. An example will help:
int x = 0; int tooBig = 10; int tooBigToPrint = 5; while(true){ x++; // I am going to get mighty big! if(x == tooBig){ break; } // No you're not haha. // code reaches here only until x = 10 if(x >= tooBigToPrint){ // No more printing but keep looping continue; } // code reaches here only until x = 5 // Print out x }
Do while loops
A do while
loop is very much the same as a while
loop with the exception that a do while
loop evaluates its expression after the body. This means that a do while
loop will always execute at least once before checking the loop condition:
int x= 0 do{ x++; }while(x < 10); // x now = 10
Note
Note that break
and continue
can also be used in do while
loops.
For loops
A for
loop has a slightly more complicated syntax than while
or do while
loops as it takes three parts to initialize. Have a look at the code first then we will break it apart:
for(int i = 0; i < 10; i++){ //Something that needs to happen 10 times goes here }
The apparently obscure form of the for
loop is clearer when put like this:
for(declaration and initialization; condition; change after each pass through loop)
To clarify further we have:
- Declaration and initialization: We create a new
int
variablei
and initialize it to zero. - Condition: Just like the other loops, it refers to the condition that must evaluate to
true
for the loop to continue. - Change after each pass through loop: In the example,
i++
means that1
is added/incremented toi
on each pass. We could also usei--
to reduce/decrementi
each pass. Consider the following code:for(int i = 10; i > 0; i--){ // countdown } // blast off i = 0
Note
Note that break
and continue
can also be used in for
loops.
The for
loop essentially takes control of initialization, condition evaluation, and the control variable itself.
Loops demo app
To get started, create a new Android project called Loops
, use a Blank Activity, and leave all the other settings at their default.
Let's add a few buttons to our UI to make this more fun:
- Drag a button onto the UI and center it horizontally near the top.
- In the Properties window change the
text
property tocountUp
. - In the properties window change the
onClick
property tocountUp
. - Place a new button just below the previous one and repeat steps 2 and 3, but this time use
countDown
for thetext
property and theonClick
property. - Place a new button just below the previous one and repeat steps 2 and 3, but this time use
nested
for thetext
property and theonClick
property.
Looks are not important for this demo but the layout should look something like this next screenshot:
What is important is that we have three buttons labeled COUNTUP, COUNTDOWN, and NESTED, which call methods named countUp
, countDown
, and nested
.
Switch to the MainActivity.java
file by left-clicking the MainActivity.java tab above the editor and we can start coding our methods.
After the closing curly brace of the onCreate
method, add the countUp
method as shown next:
public void countUp(View v){ Log.i("message:","In countUp method"); int x = 0; // Now an apparently infinite while loop while(true){ // Add 1 to x each time x++; Log.i("x =", "" + x); if(x == 3){ // Get me out of here break; } } }
We will be able to call this method we have just written, from the appropriately labeled button.
After the closing curly brace of the countUp
method, add the countDown
method:
public void countDown(View v){ Log.i("message:","In countDown method"); int x = 4; // Now an apparently infinite while loop while(true){ // Add 1 to x each time x--; Log.i("x =", "" + x); if(x == 1){ // Get me out of here break; } } }
We will be able to call this method we have just written, from the appropriately labeled button.
After the closing curly brace of the countDown
method, add the nested
method:
public void nested(View v){ Log.i("message:","In nested method"); // a nested for loop for(int i = 0; i < 3; i ++){ for(int j = 3; j > 0; j --){ // Output the values of i and j Log.i("i =" + i,"j=" + j); } } }
We will be able to call this method we have just written, from the appropriately labeled button.
Now, let's run the app and start tapping buttons. If you tap each of the buttons once from top to bottom, this is the console output you will see:
message:﹕ In countUp method x =﹕ 1 x =﹕ 2 x =﹕ 3 message:﹕ In countDown method x =﹕ 3 x =﹕ 2 x =﹕ 1 message:﹕ In nested method i =0﹕ j=3 i =0﹕ j=2 i =0﹕ j=1 i =1﹕ j=3 i =1﹕ j=2 i =1﹕ j=1 i =2﹕ j=3 i =2﹕ j=2 i =2﹕ j=1
We can see that the countUp
method does exactly that. The int x
variable is initialized to zero, an infinite while
loop is entered, and x
is incremented with the increment ++
operator. Fortunately, on each iteration of the loop, we test for x
being equal to 3
with if (x == 3)
and break when this is true
.
Next, in the countDown
method, we do the same in reverse. The int x
variable is initialized to 4
, an infinite while
loop is entered, and x
is decremented with the decrement --
operator. This time, on each iteration of the loop, we test for x
being equal to 1
with if (x == 1)
and break when this is true
.
Finally, we nest two for
loops within each other. We can see from the output that for each time i
(which is controlled by the outer loop) is incremented, j
(which is controlled by the inner loop) is decremented from 3
to 1
. Look carefully at this image that shows where the start and end of each for loop is, to help fully understand this:
You can of course keep tapping to observe each button's output for as long as you like. As an experiment, try making the loops longer, perhaps 1,000.