JB Header

Java break, continue and Labeled Loops Explained

Introduction A loop normally runs until its condition becomes false. Sometimes you need to leave a loop early - you found what you were searching for - or skip the rest of one iteration - this item is invalid, move on to the next. Java's break and continue statements do exactly this. This tutorial explains break, continue and labeled loops in Java with examples. We will start with break, and use it to stop a search. We will then skip iterations with continue. Next we will see the problem with nested loops, and solve it with labeled break and continue. Lastly, we will look at return as a way out of loops, and at guidelines for keeping such code readable.

(Note - This tutorial uses the loops from the for loopClick to read tutorial: Java for Loop Tutorial with Examples and while loopClick to read tutorial: Java while and do-while Loops with Examples tutorials.) break - leaving a loop early break ends the loop it is in immediately. The program continues with the first statement after the loop. It works in for, enhanced for, while and do-while loops - and, as we saw in the switch statementClick to read tutorial: Java switch Statement Tutorial with Examples, in switch. A typical use is stopping a search as soon as the item is found -
Stopping a search with break
//BreakSearch.java
public class BreakSearch {
  public static void main(String[] args) {
    int[] orderIds = {1042, 1077, 1093, 1105, 1150};
    int wanted = 1093;
    int position = -1;
    for (int i = 0; i < orderIds.length; i++) {
      System.out.println("Checking position " + i);
      if (orderIds[i] == wanted) {
        position = i;
        break;
      }
    }
    if (position >= 0) {
      System.out.println("Found " + wanted + " at position " + position);
    } else {
      System.out.println(wanted + " not found");
    }
  }
}
 OUTPUT of the above code
Checking position 0
Checking position 1
Checking position 2
Found 1093 at position 2
The loop stopped at position 2, without checking the last two elements. For a large array, stopping early can save a lot of work. continue - skipping to the next iteration continue skips the rest of the current iteration, and goes straight on to the next one. In a for loop, the update part (such as i++) still runs; in a while loop, the condition is checked next.
Skipping invalid values with continue
//ContinueSkip.java
public class ContinueSkip {
  public static void main(String[] args) {
    int[] readings = {23, -1, 25, 999, 24, -1, 26};
    int sum = 0;
    int valid = 0;
    for (int r : readings) {
      if (r < 0 || r > 100) {
        System.out.println("Skipping bad reading " + r);
        continue;
      }
      sum += r;
      valid++;
    }
    System.out.println(valid + " valid readings, average = " + (double) sum / valid);

    System.out.print("Odd numbers below 10: ");
    for (int i = 0; i < 10; i++) {
      if (i % 2 == 0) {
        continue;
      }
      System.out.print(i + " ");
    }
    System.out.println();
  }
}
 OUTPUT of the above code
Skipping bad reading -1
Skipping bad reading 999
Skipping bad reading -1
4 valid readings, average = 24.5
Odd numbers below 10: 1 3 5 7 9
Using continue at the top of a loop body, for the cases to skip, keeps the main work of the loop un-nested - the same idea as guard clausesClick to read tutorial: Java if, else if and else Statements with Examples in methods.
The problem with nested loops An ordinary break or continue only affects the innermost loop it is in. When searching a grid with nested loops, a plain break leaves the inner loop, but the outer loop carries on -
break only leaves the inner loop
//NestedBreakProblem.java
public class NestedBreakProblem {
  public static void main(String[] args) {
    int[][] grid = {
      {3, 8, 1},
      {9, 7, 4},
      {2, 7, 6}
    };
    for (int row = 0; row < grid.length; row++) {
      for (int col = 0; col < grid[row].length; col++) {
        if (grid[row][col] == 7) {
          System.out.println("Found 7 at row " + row + ", col " + col);
          break;
        }
      }
    }
  }
}
 OUTPUT of the above code
Found 7 at row 1, col 1
Found 7 at row 2, col 1
We wanted only the first 7, but the outer loop went on to the next row and found the second one too. Labeled break and continue A label is a name followed by a colon, placed just before a loop - search:. break search; then ends the labeled loop, however deeply it is nested, and continue search; skips to the next iteration of the labeled loop.
Labeled break and continue
//LabeledLoops.java
public class LabeledLoops {
  public static void main(String[] args) {
    int[][] grid = {
      {3, 8, 1},
      {9, 7, 4},
      {2, 7, 6}
    };

    search:
    for (int row = 0; row < grid.length; row++) {
      for (int col = 0; col < grid[row].length; col++) {
        if (grid[row][col] == 7) {
          System.out.println("Found the first 7 at row " + row + ", col " + col);
          break search;
        }
      }
    }

    String[] orders = {"A1 ok", "B2 ok", "C3 DAMAGED", "D4 ok"};
    String[][] items = {{"pen", "ink"}, {"book"}, {"lamp", "bulb"}, {"mug"}};
    orders:
    for (int i = 0; i < orders.length; i++) {
      for (String item : items[i]) {
        if (orders[i].contains("DAMAGED")) {
          System.out.println("Order " + orders[i] + " skipped");
          continue orders;
        }
        System.out.println("Packing " + item + " for " + orders[i]);
      }
    }
  }
}
 OUTPUT of the above code
Found the first 7 at row 1, col 1
Packing pen for A1 ok
Packing ink for A1 ok
Packing book for B2 ok
Order C3 DAMAGED skipped
Packing mug for D4 ok
Explanation of the code
  • break search; ended both loops at once, so only the first 7 was reported.
  • continue orders; abandoned the damaged order's items and moved straight on to the next order.
  • A label can only be used by break or continue statements inside the labeled loop. Labels are not goto - you cannot jump to an arbitrary place.
  • Label names follow the identifier rules. Unlike variables, labels and variables can share a name, as orders does here - although choosing different names is clearer.
return - leaving a loop and the method return ends the whole method, and with it every loop inside the method. Moving a search into its own method and returning as soon as the answer is found is often clearer than a labeled break.
Returning from inside nested loops
//ReturnFromLoop.java
public class ReturnFromLoop {
  static String findFirst(int[][] grid, int target) {
    for (int row = 0; row < grid.length; row++) {
      for (int col = 0; col < grid[row].length; col++) {
        if (grid[row][col] == target) {
          return "row " + row + ", col " + col;
        }
      }
    }
    return "not found";
  }

  public static void main(String[] args) {
    int[][] grid = {{3, 8, 1}, {9, 7, 4}, {2, 7, 6}};
    System.out.println("First 7: " + findFirst(grid, 7));
    System.out.println("First 5: " + findFirst(grid, 5));
  }
}
 OUTPUT of the above code
First 7: row 1, col 1
First 5: not found
Guidelines
  • Use break to stop a search or a while (true) loop as soon as you have the answer.
  • Use continue at the start of a loop body to skip items which need no work.
  • Too many break and continue statements make a loop hard to follow. If a loop has several, consider a clearer loop condition, or moving the loop into a method which uses return.
  • Use labels sparingly. They are the right tool for leaving nested loops, but an extracted method is often more readable.
Summary In this tutorial we first used break to leave a loop early, stopping a search as soon as the item was found. We then used continue to skip the rest of an iteration, ignoring invalid readings. Next we saw that plain break and continue affect only the innermost loop, and used labeled break and continue to control an outer loop. Lastly, we used return to leave nested loops from a method, and went through guidelines for readable loops. This completes control flow. In the next tutorial, we start on arraysClick to read tutorial: Java Arrays Tutorial: Declare, Create and Initialize.

Java break, continue and Labeled Loops Explained - JavaBrahman