Question
I have a nested loop in Java like this:
for (Type type : types) {
for (Type t : types2) {
if (someCondition) {
// Do something and then stop looping
break; // This only breaks the inner loop
}
}
}
How can I break out of both loops?
I have looked at similar questions, but many of the solutions use goto, which Java does not support in that way. I also do not want to:
- move the inner loop into a separate method
- use
returnto exit from the surrounding method
I want to stop executing the nested loop block entirely when the condition is met.
Short Answer
By the end of this page, you will understand how break works in nested loops in Java, how to exit multiple loops using a labeled break, and when alternatives like boolean flags or early return are more appropriate.
Concept
In Java, a normal break statement only exits the nearest enclosing loop or switch. In a nested loop, that means it stops only the inner loop.
When you need to stop both the inner and outer loop, Java gives you a feature called a labeled break. A label is a name placed before a loop. You can then write break labelName; to exit that specific loop, even if you are currently inside a deeper nested loop.
This matters because nested loops are common in real programs:
- searching through combinations of values
- comparing items from two collections
- scanning rows and columns in a grid
- stopping as soon as a match is found
Without a clear way to exit multiple loops, code can become messy, slow, or harder to read. Java's labeled break is the direct language feature for this situation.
Mental Model
Think of nested loops like walking through a building:
- the inner loop is the current room
- the outer loop is the whole floor
A normal break says: leave this room.
A labeled break says: leave this floor.
So if you are deep inside a nested structure and want to stop the whole process, a labeled break lets you jump out to the exact loop you named.
Syntax and Examples
Basic break
A normal break exits only the nearest loop:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) {
break;
}
System.out.println(i + "," + j);
}
}
Here, break stops only the inner for loop.
Labeled break
To break out of both loops, add a label to the outer loop:
outerLoop:
for (Type type : types) {
for (Type t : types2) {
if (someCondition) {
// Do something
break outerLoop;
}
}
}
How it works
outerLoop:is a label attached to the outer loop.break outerLoop;exits that labeled loop.- Because the inner loop is inside the outer loop, both loops stop.
Example with real values
List<Integer> nums1 = List.of(1, 2, 3);
List<Integer> nums2 = List.of(10, 20, 30);
search:
for (int a : nums1) {
for (int b : nums2) {
if (a + b == 22) {
System.out.println("Found: " + a + " + " + b);
break search;
}
}
}
This prints:
Found: 2 + 20
As soon as the match is found, both loops end.
Alternative: using a flag
If you prefer not to use labels, you can use a boolean variable:
boolean found = false;
for (Type type : types) {
for (Type t : types2) {
if (someCondition) {
// Do something
found = true;
break;
}
}
if (found) {
break;
}
}
This works, but it is more verbose than a labeled break.
Step by Step Execution
Consider this code:
outer:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
System.out.println("i=" + i + ", j=" + j);
if (i == 2 && j == 2) {
break outer;
}
}
}
System.out.println("Done");
Step by step
- The label
outer:is attached to the outerforloop. i = 1starts.- Inner loop runs with
j = 1,j = 2, andj = 3. - Then
i = 2starts. - Inner loop runs with
j = 1. - Then
j = 2. - The condition
i == 2 && j == 2becomes true. break outer;runs.- Java exits the loop labeled
outer, which means the outer loop ends immediately. - Execution continues after the loop block.
Doneis printed.
Output
i=1, j=1
i=1, j=2
i=1, j=3
i=2, j=1
i=2, j=2
Done
Notice that values after i=2, j=2 are never reached.
Real World Use Cases
Nested loop exits appear in many practical situations:
Searching for the first match
outer:
for (String username : usernames) {
for (String banned : bannedNames) {
if (username.equals(banned)) {
System.out.println("Blocked user found: " + username);
break outer;
}
}
}
Scanning a 2D grid
int[][] board = {
{0, 0, 0},
{0, 1, 0},
{0, 0, 0}
};
find:
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
if (board[row][col] == 1) {
System.out.println("Found at row " + row + ", col " + col);
break find;
}
}
}
Comparing two collections until a duplicate is found
stop:
for (String a : listA) {
for (String b : listB) {
if (a.equals(b)) {
System.out.println("Duplicate found: " + a);
break stop;
}
}
}
This is useful when finding the first result is enough and continuing the loops would waste time.
Real Codebase Usage
In real Java codebases, developers usually choose among these patterns:
1. Labeled break for immediate loop exit
Good when:
- you are inside nested loops
- stopping both loops is the clearest option
- the logic is local and easy to follow
search:
for (Order order : orders) {
for (Item item : order.getItems()) {
if (item.getId().equals(targetId)) {
foundItem = item;
break search;
}
}
}
2. Guard variables when labels feel unclear
Some teams avoid labels for readability reasons and use a boolean flag instead.
boolean shouldStop = false;
for (Order order : orders) {
for (Item item : order.getItems()) {
if (item.getId().equals(targetId)) {
foundItem = item;
shouldStop = true;
break;
}
}
if (shouldStop) {
break;
}
}
3. Early return from a method
This is often the cleanest option when the loop is inside a method whose job is to find or process something.
public Item findItem(List<Order> orders, String targetId) {
for (Order order : orders) {
for (Item item : order.getItems()) {
if (item.getId().equals(targetId)) {
return item;
}
}
}
return null;
}
Your question specifically avoids this approach, but it is common in production code.
4. Stream or collection-based redesign
Sometimes nested loops suggest that a Set, Map, or stream pipeline could simplify the logic. But for straightforward control flow, a labeled break is often simpler and faster to understand.
Common Mistakes
Mistake 1: Expecting break to exit all loops
Broken example:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break;
}
}
}
This exits only the inner loop.
Fix
Use a labeled break if you want to stop the outer loop too:
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break outer;
}
}
}
Mistake 2: Putting the label in the wrong place
Broken example:
for (int i = 0; i < 3; i++) {
inner:
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break inner;
}
}
}
This still only exits the inner loop because the label is attached to the inner loop.
Fix
Attach the label to the loop you want to exit.
Mistake 3: Using too many labels
Labels are useful, but too many can make code harder to follow.
Avoid
- deeply nested labels
- unclear names like
x:orlabel1:
Prefer
- meaningful names like
search:,scanGrid:, orouterLoop:
Mistake 4: Forgetting that code after the loop still runs
break outer; exits the loop, not the whole method.
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
break outer;
}
}
System.out.println("This still runs");
If you want to exit the entire method, use return instead.
Comparisons
| Approach | Exits inner loop only | Exits outer loop too | Exits method | Best when |
|---|---|---|---|---|
break | Yes | No | No | You only want to stop the current loop |
break label; | Yes | Yes | No | You want to stop a specific outer loop |
| Boolean flag | Yes | Yes, with extra checks | No | You want to avoid labels |
return | Yes | Yes | Yes | The method should end immediately |
continue | No | No | No | You want to skip to the next iteration |
continue label; | No | Skips to next iteration of labeled loop | No | You want to keep looping, but at an outer level |
break vs break label
break;
- exits the nearest loop
break outer;
- exits the loop named
outer
break label vs return
break labelstops the loop block and continues with the next statement after itreturnleaves the entire method immediately
Cheat Sheet
// Normal break: exits nearest loop only
break;
// Labeled break: exits the named outer loop
outer:
for (...) {
for (...) {
if (condition) {
break outer;
}
}
}
Rules
- A plain
breakexits only the closest enclosing loop orswitch. - A labeled
breakexits the loop with that label. - The label must appear before the loop statement.
- Java does not use
gotofor this. - After
break label;, execution continues after the labeled loop.
Good label names
outersearchscanGridfindMatch
Alternative pattern
boolean found = false;
for (...) {
for (...) {
if (condition) {
found = true;
break;
}
}
if (found) {
break;
}
}
Edge case
If the label is attached to the inner loop, break thatLabel; will not exit the outer loop.
FAQ
How do you break out of two nested loops in Java?
Use a labeled break:
outer:
for (...) {
for (...) {
if (condition) {
break outer;
}
}
}
Does Java support goto for breaking loops?
No. Java reserves the word goto, but it is not used as a control-flow statement. Use labeled break or continue instead.
Is labeled break bad practice in Java?
Not necessarily. It is acceptable when it clearly solves a nested-loop exit problem. Overusing labels can hurt readability, but a single well-named label is often fine.
What is the difference between break and return in Java?
break exits a loop or switch. return exits the entire method.
Can I use continue with labels in Java?
Yes. continue label; skips to the next iteration of the labeled loop.
Should I use a boolean flag instead of a label?
Use whichever makes the code clearer. A label is shorter and built for this exact situation. A flag may feel more explicit to some teams.
Will code after the loops still execute after break outer;?
Yes. Java continues with the next statement after the labeled loop block.
Mini Project
Description
Build a small Java program that searches a seating chart for the first reserved seat. This demonstrates how to stop scanning a two-dimensional structure as soon as a match is found, which is a common use case for breaking out of nested loops.
Goal
Create a program that searches a 2D array and stops both loops immediately when the first target value is found.
Requirements
- Create a 2D array representing a seating chart or grid.
- Use nested loops to scan through each row and column.
- Stop both loops as soon as the target value is found.
- Print the location of the found item.
- Print a message if the target value does not exist.
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.