Thursday, 26 April 2018

Core Java: Break and Continue

break and continue - Interrupting Loop Flow
 
The break statement breaks out and exits the current (innermost) loop.
The continue statement aborts the current iteration and continue to the next iteration of the current (innermost) loop.
 
break and continue are poor structures as they are hard to read and hard to follow. Use them only if absolutely necessary.
 
Example (break): The following program lists the non-prime numbers between 2 and an upperbound.
/*
 * List all non-prime numbers between 2 and an upperbound
 */
public class NonPrimeList {
   public static void main(String[] args) {
      int upperbound = 100;
      for (int number = 2; number <= upperbound; ++number) {
         // Not a prime, if there is a factor between 2 and sqrt(number)
         int maxFactor = (int)Math.sqrt(number);
         for (int factor = 2; factor <= maxFactor; ++factor) {
            if (number % factor == 0) {   // Factor?
               System.out.println(number + " is NOT a prime");
               break;   // A factor found, no need to search for more factors
            }
         }
      }
   }
}
 
Let's rewrite the above program to list all the primes instead. A boolean flag called isPrime is used to indicate whether the current number is a prime. It is then used to control the printing.
 
/*
 * List all prime numbers between 2 and an upperbound
 */
public class PrimeListWithBreak {
   public static void main(String[] args) {
      int upperbound = 100;
      for (int number = 2; number <= upperbound; ++number) {
         // Not a prime, if there is a factor between 2 and sqrt(number)
         int maxFactor = (int)Math.sqrt(number);
         boolean isPrime = true;  // boolean flag to indicate whether number is a prime
         for (int factor = 2; factor <= maxFactor; ++factor) {
            if (number % factor == 0) {   // Factor?
               isPrime = false;   // number is not a prime
               break;   // A factor found, no need to search for more factors
            }
         }
         if (isPrime) System.out.println(number + " is a prime");
      }
   }
}
 
Let's rewrite the above program without using break statement. A while loop is used (which is controlled by the boolean flag) instead of for loop with break.
 
/*
 * List all prime numbers between 2 and an upperbound
 */
public class PrimeList {
   public static void main(String[] args) {
      int upperbound = 100;
      for (int number = 2; number <= upperbound; ++number) {
         // Not prime, if there is a factor between 2 and sqrt of number
         int maxFactor = (int)Math.sqrt(number);
         boolean isPrime = true;
         int factor = 2;
         while (isPrime && factor <= maxFactor) {
            if (number % factor == 0) {   // Factor of number?
                isPrime = false;
            }
            ++factor;
         }
         if (isPrime) System.out.println(number + " is a prime");
      }
   }
}
 
Example (continue):
 
/*
 * Sum 1 to upperbound, exclude 11, 22, 33,...
 */
int upperbound = 100;
int sum = 0;
for (int number = 1; number <= upperbound; ++number) {
   if (number % 11 == 0) continue;  // Skip the rest of the loop body, continue to the next iteration
   sum += number;
}
// It is better to re-write the loop as:
for (int number = 1; number <= upperbound; ++number) {
   if (number % 11 != 0) sum += number;
}
 
Example (break and continue): Study the following program.
 
/*
 * A mystery series created using break and continue
 */
public class MysterySeries {
   public static void main(String[] args) {
      int number = 1;
      while(true) {
         ++number;
         if ((number % 3) == 0) continue;
         if (number == 133) break;
         if ((number % 2) == 0) {
            number += 3;
         } else {
            number -= 3;
         }
         System.out.print(number + " ");
      }
   }
}

Labeled break
 
In a nested loop, the break statement breaks out the innermost loop and continue into the outer loop. At times, there is a need to break out all the loops (or multiple loops). This is clumsy to achieve with boolean flag, but can be done easily via the so-called labeled break. You can add a label to a loop in the form of labelName: loop. For example,
 
level1:          // define a label for the level-1 loop
for (.....) {
level2:          // define a label for the level-2 loop
   for (.....) {
      for (......) {  // level-3 loop
         if (...) break level1;  // break all loops, continue after the loop
         if (...) break level2:  // continue into the next statement of level-1 loop
         ......
      }
   }
}
 
Labeled continue
 
In a nested loop, similar to labeled break, you can use labeled continue to continue into a specified loop. For example,
 
level1:          // define a label (with : suffix) for the level-1 loop
for (.....) {
level2:          // define a label (with : suffix) for the level-2 loop
   for (.....) {
      for (......) {  // level-3 loop
         if (...) continue level1;  // continue the next iteration of level-1 loop
         if (...) continue level2:  // continue the next iteration of level-2 loop
         ......
      }
   }
}
 
Again, labeled break and continue are not structured and hard to read. Use them only if absolutely necessary.
 
Example (Labeled break): Suppose that you are searching for a particular number in a 2D array.
 
public class TestLabeledBreak {
   public static void main(String[] args) {
      int[][] testArray = {
         {1, 2, 3, 4},
         {4, 3, 1, 4},
         {9, 2, 3, 4}
      };

      int magicNumber = 8;
      boolean found = false;
      mainLoop:
      for (int i = 0; i < testArray.length; ++i) {
         for (int j = 0; j < testArray[i].length; ++j) {
            if (testArray[i][j] == magicNumber) {
               found = true;
               break mainLoop;
            }
         }
      }
      System.out.println("Magic number " + (found ? "found" : "NOT found"));
   }
}

No comments:

Post a Comment

Please write your view and suggestion....