break and continue are the two keywords that let you step out of a loop early or skip to the next pass, and a label attached to a loop lets you leave nested loops instead of only the innermost one. Used sparingly they make a loop express its own exit conditions clearly.
What does break do inside a loop?
break ends the loop that contains it and carries on with the statement after that loop. It is the way to say "we have found what we were looking for, stop searching" without writing a flag variable or a complicated condition.
public class FindFirstMatch {
public static void main(String[] args) {
int[] readings = {12, 45, 78, 91, 23};
int target = 78;
for (int i = 0; i < readings.length; i++) {
if (readings[i] == target) {
System.out.println("Found " + target + " at index " + i);
break;
}
System.out.println("checked index " + i);
}
System.out.println("scan finished");
}
}The output shows the scan stopping as soon as the target turned up:
checked index 0
checked index 1
Found 78 at index 2
scan finishedWithout the break the loop would have carried on and checked index 3 as well. The final line still prints either way, because break leaves the loop rather than ending the program.
What does continue do inside a loop?
continue abandons the rest of the current pass and jumps straight to the next one. For a for loop it means the update expression still runs; for a while loop it means the condition is re-tested. Use it to skip data you do not want without wrapping the rest of the body in an else.
public class SkipBadReadings {
public static void main(String[] args) {
int[] readings = {10, -1, 25, 0, 33};
int valid = 0;
int sum = 0;
for (int r : readings) {
if (r <= 0) {
continue;
}
valid++;
sum += r;
}
System.out.println("valid readings: " + valid);
System.out.println("sum: " + sum);
}
}Only the three positive readings counted:
valid readings: 3
sum: 68Written with continue, the counting logic stays at the top level of the loop body instead of being buried in an else branch. That is the real benefit: the interesting code is not indented one level deeper for the sake of a guard.
How do labels let you break out of nested loops?
By default break only ends the innermost loop. When you have two loops nested and you want to abandon both, put a label before the outer loop and repeat that label at the break.
public class NestedSearch {
public static void main(String[] args) {
int[][] grid = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int target = 5;
boolean found = false;
outer:
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
if (grid[row][col] == target) {
found = true;
System.out.println("Found " + target + " at row " + row + ", column " + col);
break outer;
}
}
}
System.out.println("scan finished, found=" + found);
}
}The output is:
Found 5 at row 1, column 1
scan finished, found=trueThe label goes on its own line, immediately before the loop, and the break names it. Without the label the break would only end the inner loop and the outer one would keep scanning the remaining rows, which is exactly what you want when you are looking for every match rather than the first one.
When is a labeled continue useful?
A labeled continue jumps to the next pass of the labelled loop, skipping the rest of the inner loop as well. It is the tool for "this row is finished, move on".
public class LabeledContinue {
public static void main(String[] args) {
int[][] grid = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
outer:
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
if (grid[row][col] % 2 == 0) {
continue outer;
}
System.out.println("odd value " + grid[row][col] + " at " + row + "," + col);
}
}
}
}Only two values printed:
odd value 1 at 0,0
odd value 7 at 2,0As soon as a row contains an even number the whole row is abandoned, which is why the 3 in the first row and the 5 in the second never appear. An unlabelled continue would have skipped only the rest of the inner loop, so the row would still have been finished.
Should you use break, or return instead?
When the loop lives inside a method and the moment you find what you are looking for is also the moment the method is finished, return the value directly. It removes the flag variable and the separate break entirely.
public class FirstDivisor {
public static void main(String[] args) {
System.out.println("smallest divisor of 91: " + firstDivisor(91));
System.out.println("smallest divisor of 13: " + firstDivisor(13));
}
static int firstDivisor(int n) {
for (int d = 2; d * d <= n; d++) {
if (n % d == 0) {
return d;
}
}
return n;
}
}The output shows a factor of 91 and the number itself for the prime 13:
smallest divisor of 91: 7
smallest divisor of 13: 13Note that the loop bound uses d * d <= n. Once the divisor passes the square root of the number no smaller factor can exist, so the method returns the number itself when nothing was found.
What is the continue trap in a while loop?
In a while loop, continue jumps to the condition check. If the statement that advances the loop sits after the continue, it never runs and the loop spins forever. Put the update before the continue, or convert the loop to a for loop where the update cannot be skipped.
public class ContinueTrap {
public static void main(String[] args) {
int i = 0;
while (i < 5) {
i++;
if (i == 3) {
continue;
}
System.out.print(i + " ");
}
System.out.println();
}
}The output skips the 3 and carries on:
1 2 4 5Move the i++ below the continue and the loop never terminates. This is the single most common way to hang a Java program, and it is the reason the advice about continue inside while loops is worth knowing.
Key takeaways
- break leaves the loop immediately; the statement after the loop still runs.
- continue skips the rest of the current pass and starts the next one, and the for loop update still happens.
- A plain break only escapes the innermost loop; a label lets you name the loop you actually want to leave.
- Labeled continue finishes the whole row or iteration and moves to the next one of the labelled loop.
- If the loop is inside a method and finding the answer ends the method, return the value instead of breaking and returning later.
- In a while loop, make sure the statement that advances the loop cannot be skipped by a continue.
Try it yourself: write a program that scans an array of ten numbers and reports the first number greater than 50, using break, then the index of that number, using a variable updated before the break. Next, print every number in the array that is not a multiple of 3, using continue. Finally, build a small 3x3 grid of numbers and use a labeled break to stop searching the moment you find a value of 7, printing the row and column; then remove the label and confirm that the search now continues into the following rows.