Explain Codes LogoExplain Codes Logo

How do I break out of nested loops in Java?

java
best-practices
functions
promises
Anton ShumikhinbyAnton Shumikhin·Sep 8, 2024
TLDR

To jump out of nested loops in Java quickly, try a labeled break. Apply the label to the outer loop and use break with the label when you'd like to exit:

myLoop: // Label for the outer loop for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (/* Magic happens */ someCondition) { break myLoop; // "Hold my beer, we're out!" — exits all loops to the labeled one } } }

Notice: Labels are valid identifiers followed by a colon. In a break context, it halts the labeled loop, not just the innermost one.

Labeled breaks insights

Breaking with style in methods

Refactor bulky loops to methods for better readability and structure with style:

public void processMatrix() { for(int i = 0; i < matrix.length; i++) { if (/* Finish him! */ findAndProcess(matrix[i])) { // Victory! return; } } } private boolean findAndProcess(int[] array) { for(int value : array) { if (/* Fatality! */ checkCondition(value)) { /* Say hello to my little friend! */ processValue(value); return true; } } return false; }

Smooth exits with boolean flags

Employ boolean flags for control flow. A clever way to signal the loop exit:

boolean flag = false; for (int i = 0; i < 5 && !flag; i++) { for (int j = 0; j < 5; j++) { if (/* Showtime! */ someCondition) { flag = true; break; // "Flag it and bag it!" } } }

Scoped exits with named blocks

Use named blocks to easily identify the scope of breaks:

Search: { // Makes exits as clear as a bell! for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (/* Eureka! */ someCondition) { break Search; } } } }

Handling nested loops like a pro

Steer away from goto logic by crafting your loops and breaks smartly:

outer: for (int a = 0; a < 5; a++) { for (int b = 0; b < 5; b++) { for (int c = 0; c < 5; c++) { if (/* It's a match! */ someComplexCondition) { continue outer; // "Next shelf, please!" } } } }

Highlighted loops of different types work like charm:

search: for (Item item : items) { for (Part part : item.getParts()) { if (/* Houston, we have a piece */ part.needsProcessing()) { /* One small step */ process(part); break search; // "Mission accomplished, let's get back!" } } }

Tips and cautions in a nutshell

  • Using labels a lot can be counterproductive - might confuse readers
  • Rethink your algorithm - if you continually have to break from multiple loops, consider refactoring
  • Comment your labeled break usages to keep the code readable and maintainable