Sometimes, an application needs to run in a loop to execute a task multiple times. As an example, if we have an array of movies and we are looking for a specific movie (Casino Royal), then we need to run in a loop and for each run, keep comparing the specific movie (Casino Royal) to that of the loop's current movie; we keep doing this until we find the movie we are looking for.
Java provides three different constructs for looping: (1) while loop (2) do-while loop, and (3) for loop. The three loop variants behave differently. So, let us begin by providing a flow-chart that highlights their behavior:
The while loop is quite simple. The looping happens as long as a specified condition is true and we quit the loop when the condition becomes false. Naturally, after every round, we need to update the loop state (or the condition variable) so that we can re-check if the condition has become true; in the above example, updating the loop state could be as simple as incrementing a counter variable.
The do-while loop also has a similar format, except that the while clause sits at the very end of the loop block. The distinctive feature of this variant is that the looping block would get executed at least once. This happens because even if the condition is false, the program must run starting from "do" till the point where it reaches the "while" condition. For cases, where we need to run the loop for the first round, whether condition is met or not, we should consider deploying "do-while" method.
The "for" loop cleanly tucks different phases of looping in one expression: initialization, conditional-check, and update conditional variable. The first part of the for loop is the initialization (e.g., "counter=0"), the second part is the loop-termination (e.g., "counter < 3"), and the last part is updating the conditional variable (e.g., "counter++"). Note that both initialization and updating the loop state is done automatically by the for-loop. We just need to specify it in the for-expression. For while and do-while loops, the above flow-chart shows that we do the task and then update the conditional variable, but the ordering can also be otherwise and should be dictated by the application logic -- it is possible that in some cases, we update the condition first and then do the task.
Before we proceed any further, let us now take a look at a pseudo-code for these three variants. Please note the semi-colon at the end of the do-while clause.
/* while loop */ while (condition) { Do the task Update the loop state } /* do-while loop */ do { Do the task Update the loop state } while (condition); /* for loop */ for (initialize; check condition; update the loop state) { Do the task }
Like conditional and switch statements, loops could also be nested. A nested loop could have a for loop inside a for loop or a while inside a while or a do-while inside a do-while. It is also quite common to use any combination (for, while, do-while) of loops. Let us understand nested loops using the following flow-chart.
/* Nested loops */ while (condition) { Do the task Update the loop state /* This could be a while or for or a do-while */ for (initialize; check condition; update the loop state) { Do the task } } /* Nested For loop */ for (initialize; check condition; update the loop state) { Do the task for (initialize; check condition; update the loop state) { Do the task } }
Now that we have seen an overview of these looping variants, it is time to put our learning to test. For that, we can use an example that has an array and prints the values using loops.
public class LoopsExample { public static void main(String[] args) { int arrayVar[] = new int[4]; int arrayValue = 880; System.out.println ("\n Filling the array using For Loop....."); // Fill the array using for loop. for (int count = 0; count < arrayVar.length; count++) { arrayVar[count] = arrayValue + count; System.out.println (" Count: " + count + ", Array Val: " + arrayVar[count]); } System.out.println ("\nPrinting the array using While Loop....."); /* * Declaring count again, since the one declared above is * not visible here. Its scope is confined only to that loop. */ int count = 0; // Print the array values using While loop. while (count < arrayVar.length) { System.out.println (" Array Index: " + count + ", Value: "+ arrayVar[count]); count++; } System.out.println ("\nPrinting the array using Do-While Loop....."); count = 0; do { System.out.println (" Array Index: " + count + ", Value: " + arrayVar[count]); count++; } while(count < arrayVar.length); } }
When we compile/run the above program, then we would see the following output.
Filling the array using For Loop..... Count: 0, Array Val: 880 Count: 1, Array Val: 881 Count: 2, Array Val: 882 Count: 3, Array Val: 883 Printing the array using While Loop..... Array Index: 0, Value: 880 Array Index: 1, Value: 881 Array Index: 2, Value: 882 Array Index: 3, Value: 883 Printing the array using Do-While Loop..... Array Index: 0, Value: 880 Array Index: 1, Value: 881 Array Index: 2, Value: 882 Array Index: 3, Value: 883
Sometimes, however, we need to run a program forever in a loop. For example, a network program (say a web-server) may continuously wait for requests from other applications, an interactive program may continuously wait for user-input, or a network protocol may continuously wait for a handshake message from a new peer. Such programs need to keep running and hence, require a loop with a condition that should always evaluates to True! Of course, an infinite loop could also terminate if an error occurs or if we kill the program. But that would be a different story!
All of the above three loop variants can be easily made to run till infinity.
For the while and do-while loops, we can keep the while condition always True; we can do this using "while (1)", because "1" being non-zero is always true. For the for loop, we can skip providing any loop termination clause; we can do this using "for(;;)". With this change, there is no termination-condition and the loop will run happily forever!