|
|
1. THE JAVA "WHILE" LOOP CONSTRUCT |
The "while" loop construct is traditionally used to implement variable count loops (although, in Java, this can also be achieved with a "for" loop) which are therefore often referred to as while loops. (As we will see while loops can also be used to implement fixed count loops --- but more of this later.) A variable count loop is used when the number of iterations associated with a loop construct is not known in advance. What is known, however, is that it should continue provided a certain condition is true. When the condition becomes false, the repetition stops. The Java while loop statement has the following format: |
The "Test expression" is used to test a loop control variable. When the expression evaluates to false the loop terminates. So that the loop has a "chance" of terminating the control variable must be "updated" on each iteration. Note that the loop control variable is initialised somewhere before commencement of the construct (the "start expression"). |
3. WHILE LOOP OR FOR LOOP? |
The above code could equally well have been implemented using a Java "for" loop as shown in Table 2. Similarly the "Smiley" face program described earlier can be implemented using a "while" loop (Table 3). So when should we use a "for" loop and when a "while" loop --- both are pre-test loops and both can be used for fixed and variable count loops? This is not a problem in languages where "for" loops can only be used to describe fixed count loops (e.g. Ada, Pascal, BASIC), the answer is: |
In Java where for and while statements can be used to describe both fixed and variable count loops, it is simply a matter of personal choice! |
// EULER'S NUMBER APROXIMATION CLASS // Frans Coenen // Wednesday 14 April 1999 // Revised Wednesday 23 August 2005 // The University of Liverpool, UK class EulerVer2 { // ------------------ METHODDS ----------------------- /* Main method */ public static void main(String[] args) { final double LIMIT = 0.000001; final int START_VALUE = 1; double termValue = 1.0; double estimationFor_e = 1.0; int termNumber = START_VALUE; // Calculation for( ;termValue>LIMIT;termNumber++) { System.out.printf("%.5f\t",termValue); termValue = termValue/(double) termNumber; estimationFor_e = estimationFor_e + termValue; } // Output System.out.println("\nNumber of terms = " + (termNumber-1)); System.out.printf("Approximation = %.5f\n",estimationFor_e); } } |
Table 2: Euler's number program
implemented using a for
loop
// SMILEY FACE APPLICATION CLASS // Frans Coenen // Tuesday 13 April 1999 // The University of Liverpool, UK class SmileyFace { // ------------ METHODS ----------------- /* Main method */ public static void main(String[] args) { int loopParameter = 0; final int END_CONDITION = 10; // While loop while (loopParameter < END_CONDITION) { System.out.print("(-:\t"); loopParameter++; } // End System.out.println("\n"); } } |
Table 3: Smiley face program implemented using a while loop
4. CONTINUOUS LOOPS AND THE BREAK STATEMENT |
Sometimes there is a need to terminate a loop somewhere in the middle. Many programming languages therefore support a break statement --- including Java. This has already been introduced in connection with switch statements, but can also be used to "break out" of a loop. Wherever possible "loop break" statements should be avoided as they alter the flow of control associated with loop statements from a clear "in at the top" to "out at the bottom" to something which is less obvious. In Java a break statement can sometimes "legitimately" be used to "break out" of a continuous loop. However, in most cases there is an alternative strategy that will avoid the use of a break. In Java we may write continuous loops using a for statement thus: for ( ; ;) { < STATEMENTS TO BE REPEATED INDEFINITELY > } or a while statement: while (true) { < STATEMENTS TO BE REPEATED INDEFINITELY > } |
(Note that the test exoression is the Boolean value true here which
always succeeds, i.e. evaluates to "true".) Continuous loops are sometimes used
when awaiting a particular input which is tested for on each iteration. If found a
break statement may then be used to break out of the loop:
if ( < SOME CONDITION > ) break; Consider the menu example application program described previously. This included a method that displayed a menu and allowed the user to enter a menu option, and another method to process the selected option using a switch statement which incorporated an error recovery mechanism in the event of an erroneous user input. An alternative implementation might be to use a continuous loop which kept repeating until a correct selector was input. This is illustrated in Table 4. On each iteration of this loop a test is made (using an "if" construct) to check the input, and if appropriate to "jump" out of the loop using a break statement. |
// MENU INTERFACE EXAMPLE APPLICATION // Frans Coenen // Thursday 15 April 1999 // Revised: Tuesday 26 July 2005 // The University of Liverpool, UK import java.util.*; class MenuInterfaceEx2App { // ------------------- FIELDS ------------------------ // Create Scanner class instance private static Scanner input = new Scanner(System.in); // ------------------ METHODS ------------------------ /* Main method */ public static void main(String[] args) { // Output menu int selector = outputMenu(); // Process selection processSelector(selector); } /* Outpur menu */ private static int outputMenu() { int selector = 0; while (selector < 1 || selector > 4) { System.out.println("PROGRAMMING PARADIGMS"); System.out.println("====================="); System.out.println("1. Imperative"); System.out.println("2. Object oriented"); System.out.println("3. Logic"); System.out.println("4. Functional"); System.out.println("Select option: "); selector = input.nextInt(); } // Return return(selector); } /* Process selector. If unrecognised selection output error message and repeat. */ private static void processSelector(int selector) { switch (selector) { case 1: System.out.println("Example languages include C, Ada and " + "Pascal"); break; case 2: System.out.println("Example languages include Java, Eiffel " + " and C++"); break; case 3: System.out.println("Example languages include Prolog"); break; case 4: System.out.println("Example languages include Lisp and " + " Miranda"); break; default: System.out.println("ERROR: Unrecognised error in switch " + " statement"); } } } |
Table 4: Alternative implementation for menu interface example program
As noted above there is usually an appropriate alternative that avoids the need for a break statement. This is true in the case of the menu example in that we could have written the method as follows:
/* Output menu */ private static int outputMenu() { int selector = 0; while (selector < 1 || selector > 4) { System.out.println("PROGRAMMING PARADIGMS"); System.out.println("====================="); System.out.println("1. Imperative"); System.out.println("2. Object oriented"); System.out.println("3. Logic"); System.out.println("4. Functional"); System.out.println("Select option: "); selector = input.nextInt(); } // Return return(selector); }
In the above code we have used a variable count while loop which repeats until an appropriate selection is made (the selector doubles up as the loop control parameter). Note that because we are using a pretest loop construct we must initialise the selector with a value that is outside of the required range of 1 to 5 inclusive. An alternative loop construct, which would not require such an initialisation, is a post test loop where we test the user's input at the end of each iteration (more on this later).
5. MISSING CONTROL EXPRESSIONS IN "FOR" LOOPS |
Although a for loop usually comprises (1) a "start expression" to initialise the loop control variable, (2) a "test expression" to determined whether to continue the loop or not, and (3) an "update expression" to incremented/decremented the control variable. It is not necessary to include all or any of these. Some examples are presented in the code given in Table 5. The code given in Table 5 contains four "for" loops. The first uses the standard format with all expressions present and produces the result of adding up the sequence {1, 2, 3, 4, 5, 6, 7, 8, 9}. The second has no "start expression" as an existing data item, total, instantiated on the previous loop, is used. The loop is used to count down from 45 to 5 in steps of five. |
The third loop has no "test expression" as this is included within the loop statements. It produces a sequence where each element is produced by adding the loopCounter to the previous element in the sequence starting with the value of the data item total as set by the previous loop. Note the use of the break statement to jump out of the loop when the sequence gets to above 50! The last loop has no "update expression", this is included within the body of the loop statement. The resulting output is presented in Table 6. As noted above if we omit all the expressions a continuous loop effect is produced. For example: for ( ; ; ) System.out.println("This loop will " + ("go on for ever"); Note that we still have to include the semicolon separators. |
// FOR LOOP EXAMPLE APPLICATION // Frans Coenen // Wednesday 24 March 1999 // Revised Thursday 15 January 2004 // The University of Liverpool, UK class ForLoopsExampleApp { // ---------------- FIELDS ----------------- /* NONE */ // --------------- METHODS ------------------ /** MAIN METHOD: */ public static void main(String[] args) { // Normal for loop to determine total. int total = normalLoop(); // No start expression (start condition) total = noLoopCountInitExp(total); // No test expression (end condition) noExitContExp(total); // No update expression noIncContExp(); } /* Normal for loop to determine total. */ public static int normalLoop() { int total = 0; final int START_LOOP=1, END_LOOP=10; System.out.print("Loop 1 (total): "); for (int loopCounter=START_LOOP;loopCounter < END_LOOP;loopCounter++) total=total+loopCounter; System.out.println("Total = " + total + "\n"); return(total); } /* No loop counter initialisation expression */ public static int noLoopCountInitExp(int total) { final int DECREMENT=5, MIN_TOTAL=0; System.out.print("Loop 2 (A.P.): "); for(;total>MIN_TOTAL;total=total-DECREMENT) System.out.print(total + " "); System.out.println("\n"); return(total); } /* No exit condition expression (variable count loop) */ public static void noExitContExp(int total) { final int START_LOOP=1, MAX_TOTAL=50; System.out.print("Loop 3 (G.P.): "); for (int loopCounter=START_LOOP;;loopCounter++) { total=total+loopCounter; System.out.print(total + " "); if (total > MAX_TOTAL) break; } System.out.println("\n"); } /* No increment loop control expression */ public static void noIncContExp() { int increment=1, total; final int START_TOTAL=0, MAX_TOTAL=50, MULTIPLIER=2; System.out.print("Loop 4 (another total): "); for (total=START_TOTAL;total < MAX_TOTAL;) { total=total+increment; increment=increment*MULTIPLIER; } System.out.println("Total = " + total + "\n"); } } |
Table 5: For loops with missing expressions
$ java ForLoopsExampleApp Loop 1 (total): Total = 45 Loop 2 (A.P.): 45 40 35 30 25 20 15 10 5 Loop 3 (G.P.): 1 3 6 10 15 21 28 36 45 55 Loop 4 (another total): Total = 63 |
Table 6: Output from for loops example with missing expressions
Created and maintained by Frans Coenen. Last updated 10 February 2015