Wie kann ich in Java aus verschachtelten Schleifen ausbrechen?


1818

Ich habe ein verschachteltes Schleifenkonstrukt wie folgt:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             break; // Breaks out of the inner loop
         }
    }
}

Wie kann ich nun aus beiden Schleifen ausbrechen? Ich habe mir ähnliche Fragen angesehen, aber keine betrifft speziell Java. Ich konnte diese Lösungen nicht anwenden, da die meisten gotos verwendet wurden.

Ich möchte die innere Schleife nicht in eine andere Methode einfügen.

Ich möchte die Schleifen nicht erneut ausführen. Beim Brechen bin ich mit der Ausführung des Schleifenblocks fertig.

Antworten:


2427

Wie bei anderen Antwortenden würde ich es definitiv vorziehen , die Schleifen in eine andere Methode zu versetzen. An diesem Punkt können Sie einfach zurückkehren, um die Iteration vollständig zu beenden. Diese Antwort zeigt nur, wie die Anforderungen in der Frage erfüllt werden können.

Sie können breakmit einem Etikett für die äußere Schleife verwenden. Zum Beispiel:

public class Test {
    public static void main(String[] args) {
        outerloop:
        for (int i=0; i < 5; i++) {
            for (int j=0; j < 5; j++) {
                if (i * j > 6) {
                    System.out.println("Breaking");
                    break outerloop;
                }
                System.out.println(i + " " + j);
            }
        }
        System.out.println("Done");
    }
}

Dies druckt:

0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
Breaking
Done

286
Dies hat zu springen , um direkt nach der Schleife. Versuch es! Ja, das Label kommt vor der Schleife, aber das liegt daran, dass es die Schleife beschriftet und nicht den Ort, an den Sie gehen möchten. (Sie können auch mit einem Label fortfahren.)
Jon Skeet

2
Perl erlaubt dies auch ein eigenes Etikettensystem. Ich denke, viele Sprachen tun es - es überrascht mich kaum, dass es in Java ist.
Evan Carroll

9
@Evan - diese Behauptung ist eindeutig wahr - in Sprachen, die versprechen, dass es wahr ist. Aber Java macht dieses Versprechen nicht. Wenn eine Sprache im Widerspruch zu Ihren Annahmen steht, sind möglicherweise Ihre Annahmen schuld. In diesem Fall denke ich, dass Sie immer noch teilweise Recht haben - Prinzip der geringsten Überraschung WRT die vielen, die noch nie von dieser Form gehört (oder sie vergessen) haben break. Auch dann sind Ausnahmen eine weitere bekanntere Ausnahme (sorry). Aber ich wäre immer noch unglücklich darüber, wenn es nicht offensichtlich wäre (kleine Schleifen, Warnkommentar, wenn das Label / der Bruch immer noch nicht sichtbar genug sind).
Steve314

6
@ MuhammadBabar: outerloopist ein Label. Ich weiß nicht genau, welchen Code Sie ausprobiert haben, aber der Code in meiner Antwort wird kompiliert und läuft einwandfrei.
Jon Skeet

4
@NisargPatil Nur weil es in sonarLint ist, riecht es nicht nach Code. Es bedeutet nur, dass es einen Entwickler gab, der dies zu sonarLint mit einem persönlichen Kratzer hinzufügte, und es ist voll von solchen Regeln, die nur dann Sinn machen, wenn sie missbraucht werden oder weil ein Entwickler einen persönlichen Hasskreuzzug gegen sie hat. Beschriftete Pausen und Fortsetzungen sind eine sehr elegante Möglichkeit, um zu beschreiben, was Sie tun möchten.
John16384

402

Technisch gesehen ist die richtige Antwort, die äußere Schleife zu beschriften. In der Praxis ist es besser, den Code in eine Methode (gegebenenfalls eine statische Methode) zu externalisieren und ihn dann aufzurufen, wenn Sie an einem beliebigen Punkt innerhalb einer inneren Schleife beenden möchten.

Das würde sich für die Lesbarkeit auszahlen.

Der Code würde so etwas werden:

private static String search(...) 
{
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Do something and break...
                return search;
            }
        }
    }
    return null; 
}

Passend zum Beispiel für die akzeptierte Antwort:

 public class Test {
    public static void main(String[] args) {
        loop();
        System.out.println("Done");
    }

    public static void loop() {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (i * j > 6) {
                    System.out.println("Breaking");
                    return;
                }
                System.out.println(i + " " + j);
            }
        }
    }
}

30
Manchmal verwenden Sie mehrere lokale Variablen, die sich außerhalb der inneren Schleife befinden. Wenn Sie sie alle übergeben, kann dies klobig sein.
Haoest

1
Wie soll diese Lösung "Fertig" wie in der akzeptierten Antwort drucken?
JohnDoe

1
@ JohnDoe rufst du es an und dann druckst du System.out.println ("erledigt"); try {} finally {} innerhalb der Suchmethode ist ebenfalls eine Option.
Zo72

2
Ich denke, dies ist eine bessere Übung, aber was passiert, wenn Sie fortfahren möchten, anstatt zu brechen? Labels unterstützen entweder gleich gut (oder schlecht!), Aber ich bin mir nicht sicher, wie ich diese Logik für ein Fortfahren konvertieren soll.
Rob Grant

@RobertGrant Wenn Sie fortfahren möchten, anstatt zu unterbrechen, verschieben Sie die äußere Schleife außerhalb der loopMethode und kehren Sie von der Methode zurück, um fortzufahren.
Muhd

215

Sie können einen benannten Block um die Schleifen verwenden:

search: {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Do something and break...
                break search;
            }
        }
    }
}

40
Sie müssen keinen neuen Block erstellen, um eine Beschriftung zu verwenden.
Jon Skeet

81
Nein, aber es macht die Absicht viel klarer. Siehe den ersten Kommentar zur akzeptierten Antwort.
Bombe

2
Es ist eigentlich kein benannter Block. Nach dem Label können Sie einen beliebigen Java-Ausdruck schreiben, da ohne Label name: if(...){...}ein benannter Zustand vorliegt. :)
La VloZ Merrill

4
Dieses Konstrukt hat einen großen Vorteil gegenüber der fordirekten Kennzeichnung des . Sie können vor dem letzten Code hinzufügen }, der nur ausgeführt wird, wenn die Bedingung nie erfüllt wurde.
Florian F

2
Es ist ein benannter Block und keine benannte Schleife. Sie konnten nicht innerhalb dieser Schleife "Suche fortsetzen"; Dies ist eine völlig legale Syntax, wenn die Schleife den Namen search hat. Sie können es brechen, aber Sie können es nicht fortsetzen.
Tatarize

132

Ich benutze niemals Etiketten. Es scheint eine schlechte Praxis zu sein, sich darauf einzulassen. Folgendes würde ich tun:

boolean finished = false;
for (int i = 0; i < 5 && !finished; i++) {
    for (int j = 0; j < 5; j++) {
        if (i * j > 6) {
            finished = true;
            break;
        }
    }
}

4
Sollte das nicht && !finishedstattdessen sein || !finished? Und warum dann breaküberhaupt verwenden und nicht auch && !finishedfür die innere Schleife verwenden?
Gandalf

4
Ich bin breakin der Lage, die Schleife willkürlich zu verlassen. Wenn nach diesem ifBlock Code vorhanden ist , können breakSie dies tun, bevor er ausgeführt wird. Aber du hast recht &&. Repariert.
Elle Mundy

2
schöne Lösung! Genau so würde ich es in der Praxis machen, wenn es aus irgendeinem Grund nicht vorzuziehen ist, es in eine zusätzliche Funktion zu setzen.
Benroth

6
Es gibt ein potenzielles Problem, wenn es nach der inneren Schleife eine Logik gibt ... die weiterhin ausgeführt wird und die äußere Schleife nur
unterbrochen wird,

7
Ich verstehe nicht, warum man das so machen sollte. Personen, die mit Code arbeiten, sollten in der Lage sein, alle Funktionen einer Sprache zu nutzen. Ich verstehe, dass es wichtig ist, Code zu schreiben, den andere verstehen können, aber nicht die Verwendung offizieller Tools, die von einer Sprache bereitgestellt werden, einzuschränken und Problemumgehungen für dieselbe Funktionalität zu finden. Oder meinten Sie etwas anderes mit "schlechter Praxis"?
Codepleb

107

Sie können Etiketten verwenden:

label1: 
for (int i = 0;;) {
    for (int g = 0;;) {
      break label1;
    }
}

4
Habe eine +1 von mir. Einfach, auf den Punkt, beantwortet die Frage. Kann nicht beschuldigt werden, eine vorhandene Antwort wiederholt zu haben, weil Sie gleichzeitig geantwortet haben.
Heimdall

40

Verwenden Sie eine Funktion:

public void doSomething(List<Type> types, List<Type> types2){
  for(Type t1 : types){
    for (Type t : types2) {
      if (some condition) {
         // Do something and return...
         return;
      }
    }
  }
}

20

Sie können eine temporäre Variable verwenden:

boolean outerBreak = false;
for (Type type : types) {
   if(outerBreak) break;
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             outerBreak = true;
             break; // Breaks out of the inner loop
         }
    }
}

Abhängig von Ihrer Funktion können Sie auch die innere Schleife verlassen / verlassen:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             return;
         }
    }
}

7
Ich finde diesen Weg irgendwie überladen.
Boutta

11
Eine zusätzliche Zustandsprüfung jedes Mal durch die Schleife? Nein Danke.
Ryandenki

15

Wenn Sie breaks und gotos nicht mögen , können Sie anstelle des for-in eine "traditionelle" for-Schleife verwenden, mit einer zusätzlichen Abbruchbedingung:

int a, b;
bool abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}

2
Nicht für jede Schleife geeignet.
John McClane

1
@ JohnMcClane Und Sie spammen dies auf viele Antworten auf eine 9+ Jahre alte Frage, weil ...?
Quintec

12

Ich musste etwas Ähnliches tun, aber ich entschied mich dafür, die erweiterte for-Schleife nicht zu verwenden.

int s = type.size();
for (int i = 0; i < s; i++) {
    for (int j = 0; j < t.size(); j++) {
        if (condition) {
            // do stuff after which you want 
            // to completely break out of both loops
            s = 0; // enables the _main_ loop to terminate
            break;
        }
    }
}

Ich finde es nicht cool, alle Elemente zu wiederholen, nachdem die Bedingung erfüllt ist. Daher würde ich im anderen Fall eine Pause hinzufügen.
Boutta

@outta Ich bin mir nicht sicher, wie Sie zu diesem Schluss kommen. Sobald die Bedingung erfüllt ist, werden beide Schleifen verlassen.
Swifty McSwifterton

OK, ich habe das Teil mit der Manipulation des 's' var nicht verstanden. Aber ich finde diese Art von schlechtem Stil, da s die Größe darstellt. Dann bevorzuge ich die Antwort von ddyer mit expliziten vars: stackoverflow.com/a/25124317/15108
boutta

@boutta Sie können szu einem Wert wechseln , der kleiner als ioder izu einem Wert größer oder gleich sist. Beide sollten den Trick ausführen . Sie haben Recht mit dem Ändern s, da es später an anderer Stelle verwendet werden kann, aber das Ändern ischadet nicht, stellt nur sicher, dass das erste fornicht weiter wiederholt wird.
Zsolti

9

Ich bevorzuge es, den Schleifentests einen expliziten "Exit" hinzuzufügen. Es macht jedem Gelegenheitsleser klar, dass die Schleife möglicherweise vorzeitig endet.

boolean earlyExit = false;
for(int i = 0 ; i < 10 && !earlyExit; i++) {
     for(int j = 0 ; i < 10 && !earlyExit; j++) { earlyExit = true; }
}

Nicht für jede Schleife geeignet.
John McClane

8

Java 8- StreamLösung:

List<Type> types1 = ...
List<Type> types2 = ...

types1.stream()
      .flatMap(type1 -> types2.stream().map(type2 -> new Type[]{type1, type2}))
      .filter(types -> /**some condition**/)
      .findFirst()
      .ifPresent(types -> /**do something**/);

1
@ Tvde1 und immer noch nützlich für andere Benutzer, so sind neue Methoden und Lösungen immer willkommen
Andrei Suworkow

Wow, das ist hässlich.
DS.

7

Normalerweise kommt es in solchen Fällen zu einer aussagekräftigeren Logik, zum Beispiel zum Suchen oder Manipulieren einiger der fraglichen iterierten 'for'-Objekte, daher verwende ich normalerweise den funktionalen Ansatz:

public Object searching(Object[] types) { // Or manipulating
    List<Object> typesReferences = new ArrayList<Object>();
    List<Object> typesReferences2 = new ArrayList<Object>();

    for (Object type : typesReferences) {
        Object o = getByCriterion(typesReferences2, type);
        if(o != null) return o;
    }
    return null;
}

private Object getByCriterion(List<Object> typesReferences2, Object criterion) {
    for (Object typeReference : typesReferences2) {
        if(typeReference.equals(criterion)) {
             // here comes other complex or specific logic || typeReference.equals(new Object())
             return typeReference;
        }
    }
    return null;
}

Hauptnachteile:

  • ungefähr zweimal mehr Zeilen
  • Mehr Verbrauch von Rechenzyklen, was bedeutet, dass es aus algorithmischer Sicht langsamer ist
  • mehr Schreibarbeit

Die Profis:

  • das höhere Verhältnis zur Trennung von Bedenken aufgrund der funktionellen Granularität
  • das höhere Verhältnis von Wiederverwendbarkeit und Kontrolle der Such- / Manipulationslogik ohne
  • Die Methoden sind nicht lang, daher kompakter und leichter zu verstehen
  • höheres Lesbarkeitsverhältnis

Es geht also nur darum, den Fall über einen anderen Ansatz zu behandeln.

Grundsätzlich eine Frage an den Autor dieser Frage: Was halten Sie von diesem Ansatz?


6

Sie können alle Schleifen ohne Verwendung von label: und Flags unterbrechen.

Es ist nur eine knifflige Lösung.

Hier ist Bedingung1 die Bedingung, die verwendet wird, um von Schleife K und J zu brechen. Und Bedingung2 ist die Bedingung, die verwendet wird, um von Schleife K, J und I zu brechen.

Zum Beispiel:

public class BreakTesting {
    public static void main(String[] args) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                for (int k = 0; k < 9; k++) {
                    if (condition1) {
                        System.out.println("Breaking from Loop K and J");
                        k = 9;
                        j = 9;
                    }
                    if (condition2) {
                        System.out.println("Breaking from Loop K, J and I");
                        k = 9;
                        j = 9;
                        i = 9;
                    }
                }
            }
        }
        System.out.println("End of I , J , K");
    }
}

2
Wie würde ich dies mit for-each-Schleifen verwenden? ;)
Willi Mentzel

5
Dies funktioniert nicht, wenn Sie eine komplexere Schleifenbedingung haben, wie list.size ()> 5. Auch ist es wirklich nur ein Hack. Es ist schwer zu lesen und schlecht zu üben!
Neuron

Es ist fehleranfällig. Stellen Sie sich die innere Schleife geändert (int k = 0; k < 10; k++)und Sie haben nicht alle die fix k = 9an k = 10. Sie könnten in eine Endlosschleife geraten.
Florian F

5

Das Konzept der beschrifteten Unterbrechung wird verwendet, um verschachtelte Schleifen in Java auszubrechen. Mit der Bezeichnung der beschrifteten Unterbrechung können Sie die Verschachtelung von Schleifen an jeder Position aufheben. Beispiel 1:

loop1:
 for(int i= 0; i<6; i++){
    for(int j=0; j<5; j++){
          if(i==3)
            break loop1;
        }
    }

Angenommen, es gibt 3 Schleifen und Sie möchten die Schleife beenden3: Beispiel 2:

loop3: 
for(int i= 0; i<6; i++){
loop2:
  for(int k= 0; k<6; k++){
loop1:
    for(int j=0; j<5; j++){
          if(i==3)
            break loop3;
        }
    }
}

4
boolean broken = false; // declared outside of the loop for efficiency
for (Type type : types) {
    for (Type t : types2) {
        if (some condition) {
            broken = true;
            break;
        }
    }

    if (broken) {
        break;
    }
}

4

Wenn es sich in einer Funktion befindet, warum geben Sie es nicht einfach zurück:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
            return value;
         }
    }
}

Ich bevorzuge dieses Muster. Es hat mich oft veranlasst, die Schleifen in eine separate Funktion aufzuteilen. Mein Code war danach immer besser, deshalb mag ich diese Antwort wirklich.
Bill K

4

Beste und einfachste Methode ..

outerloop:
for(int i=0; i<10; i++){
    // here we can break Outer loop by 
    break outerloop;

    innerloop:
    for(int i=0; i<10; i++){
        // here we can break innerloop by 
        break innerloop;
     }
}

4
Diese Beispiele für das Brechen sind imho nicht sehr hilfreich, da sie auch ohne das Etikett an derselben Stelle brechen würden. Es ist auch immer schön, Code zu haben, den Sie tatsächlich ausführen können, was bei Ihrem Code nicht der Fall ist, da die innere Schleife niemals erreicht werden kann.
Neuron

Ich würde das Gleiche tippen. Die Etiketten sind in diesem Fall etwas unbrauchbar.
Taslim Oseni

4

Eher ungewöhnlicher Ansatz, aber in Bezug auf die Codelänge ( nicht die Leistung ) ist dies das Einfachste, was Sie tun können:

for(int i = 0; i++; i < j) {
    if(wanna exit) {
        i = i + j; // if more nested, also add the 
                   // maximum value for the other loops
    }
}


4

Eine andere Lösung, die ohne Beispiel erwähnt wird (sie funktioniert tatsächlich im Produktcode).

try {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition #1) {
                // Do something and break the loop.
                throw new BreakLoopException();
            }
        }
    }
}
catch (BreakLoopException e) {
    // Do something on look breaking.
}

Natürlich BreakLoopExceptionsollte es intern, privat und mit No-Stack-Trace beschleunigt sein:

private static class BreakLoopException extends Exception {
    @Override
    public StackTraceElement[] getStackTrace() {
        return new StackTraceElement[0];
    }
}

1
Es wurde tatsächlich in einer Antwort erwähnt, die -23 Stimmen erhielt ... stackoverflow.com/a/886980/2516301 . Es wird die Arbeit machen, aber es ist eine sehr schlechte Programmierpraxis ...
vefthym

tatsächlich. Ich habe jedoch einen solchen Legacy-Code gesehen - verschachtelte 4-Ebenen-Schleifen mit mehreren Unterbrechungsbedingungen. und es war mit Ausnahmen besser lesbar als mit Inline-Code. -23 Stimmen sind meistens emotionale Bewertungen, aber ja - dieser Ansatz sollte sorgfältig angewendet werden.
Ursa

1
Es wäre noch besser lesbar gewesen, wenn es in einen separaten Funktionsaufruf mit Center-Return aufgeteilt worden wäre. Oft durch einen kleinen Refactor noch besser gemacht, so dass es als eigenständige (oft wiederverwendbare) Funktion sinnvoll ist.
Bill K

2

for (int j = 0; j < 5; j++) //inner loop sollte durch ersetzt werden for (int j = 0; j < 5 && !exitloops; j++) .

In diesem Fall sollten vollständige verschachtelte Schleifen beendet werden, wenn die Bedingung erfüllt ist True. Aber wenn wir exitloopsnur nach oben verwendenloop

 for (int i = 0; i < 5 && !exitloops; i++) //upper loop

Dann wird die innere Schleife fortgesetzt, da es kein zusätzliches Flag gibt, das diese innere Schleife zum Verlassen benachrichtigt.

Beispiel: Wenn i = 3und j=2Dann ist die Bedingung false. Aber in der nächsten Iteration der inneren Schleife j=3 wird der Zustand (i*j), 9der truenur die innere Schleife ist, fortgesetzt, bis er jwird 5.

Es muss also auch exitloopsfür die inneren Schleifen verwendet werden.

boolean exitloops = false;
for (int i = 0; i < 5 && !exitloops; i++) { //here should exitloops as a Conditional Statement to get out from the loops if exitloops become true. 
    for (int j = 0; j < 5 && !exitloops; j++) { //here should also use exitloops as a Conditional Statement. 
        if (i * j > 6) {
            exitloops = true;
            System.out.println("Inner loop still Continues For i * j is => "+i*j);
            break;
        }
        System.out.println(i*j);
    }
}

2

Verwenden Sie wie im Vorschlag für @ 1800 INFORMATION die Bedingung, die die innere Schleife unterbricht, als Bedingung für die äußere Schleife:

boolean hasAccess = false;
for (int i = 0; i < x && hasAccess == false; i++){
    for (int j = 0; j < y; j++){
        if (condition == true){
            hasAccess = true;
            break;
        }
    }
}

2

Wenn es sich um eine neue Implementierung handelt, können Sie versuchen, die Logik als if-else_if-else-Anweisungen neu zu schreiben.

while(keep_going) {

    if(keep_going && condition_one_holds) {
        // Code
    }
    if(keep_going && condition_two_holds) {
        // Code
    }
    if(keep_going && condition_three_holds) {
        // Code
    }
    if(keep_going && something_goes_really_bad) {
        keep_going=false;
    }
    if(keep_going && condition_four_holds) {
        // Code
    }
    if(keep_going && condition_five_holds) {
        // Code
    }
}

Andernfalls können Sie versuchen, ein Flag zu setzen, wenn diese spezielle Bedingung aufgetreten ist, und in jeder Ihrer Schleifenbedingungen nach diesem Flag suchen.

something_bad_has_happened = false;
while(something is true && !something_bad_has_happened){
    // Code, things happen
    while(something else && !something_bad_has_happened){
        // Lots of code, things happens
        if(something happened){
            -> Then control should be returned ->
            something_bad_has_happened=true;
            continue;
        }
    }
    if(something_bad_has_happened) { // The things below will not be executed
        continue;
    }

    // Other things may happen here as well, but they will not be executed
    //  once control is returned from the inner cycle.
}

HIER! Während eine einfache Pause nicht funktioniert, kann sie mit verwendet werden continue.

Wenn Sie einfach die Logik von einer Programmiersprache nach Java portieren und nur das Ding zum Laufen bringen möchten, können Sie versuchen, Labels zu verwenden .


2

Demo für break, continueund label:

Java-Schlüsselwörter breakundcontinue haben einen Standardwert. Es ist die "nächste Schleife", und heute, nach ein paar Jahren mit Java, habe ich sie gerade bekommen!

Es scheint selten verwendet zu werden, aber nützlich.

import org.junit.Test;

/**
 * Created by cui on 17-5-4.
 */

public class BranchLabel {
    @Test
    public void test() {
        System.out.println("testBreak");
        testBreak();

        System.out.println("testBreakLabel");
        testBreakLabel();

        System.out.println("testContinue");
        testContinue();
        System.out.println("testContinueLabel");
        testContinueLabel();
    }

    /**
     testBreak
     a=0,b=0
     a=0,b=1
     a=1,b=0
     a=1,b=1
     a=2,b=0
     a=2,b=1
     a=3,b=0
     a=3,b=1
     a=4,b=0
     a=4,b=1
     */
    public void testBreak() {
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (b == 2) {
                    break;
                }
                System.out.println("a=" + a + ",b=" + b);
            }
        }
    }

    /**
     testContinue
     a=0,b=0
     a=0,b=1
     a=0,b=3
     a=0,b=4
     a=1,b=0
     a=1,b=1
     a=1,b=3
     a=1,b=4
     a=2,b=0
     a=2,b=1
     a=2,b=3
     a=2,b=4
     a=3,b=0
     a=3,b=1
     a=3,b=3
     a=3,b=4
     a=4,b=0
     a=4,b=1
     a=4,b=3
     a=4,b=4
     */
    public void testContinue() {
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (b == 2) {
                    continue;
                }
                System.out.println("a=" + a + ",b=" + b);
            }
        }
    }

    /**
     testBreakLabel
     a=0,b=0,c=0
     a=0,b=0,c=1
     * */
    public void testBreakLabel() {
        anyName:
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                for (int c = 0; c < 5; c++) {
                    if (c == 2) {
                        break anyName;
                    }
                    System.out.println("a=" + a + ",b=" + b + ",c=" + c);
                }
            }
        }
    }

    /**
     testContinueLabel
     a=0,b=0,c=0
     a=0,b=0,c=1
     a=1,b=0,c=0
     a=1,b=0,c=1
     a=2,b=0,c=0
     a=2,b=0,c=1
     a=3,b=0,c=0
     a=3,b=0,c=1
     a=4,b=0,c=0
     a=4,b=0,c=1
     */
    public void testContinueLabel() {
        anyName:
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                for (int c = 0; c < 5; c++) {
                    if (c == 2) {
                        continue anyName;
                    }
                    System.out.println("a=" + a + ",b=" + b + ",c=" + c);
                }
            }
        }
    }
}

2

Demo

public static void main(String[] args) {
    outer:
    while (true) {
        while (true) {
            break outer;
        }
    }
}

1

Sie können Folgendes tun:

  1. Setzen Sie eine lokale Variable auf false

  2. Setzen Sie diese Variable truein der ersten Schleife, wenn Sie brechen möchten

  3. Dann können Sie in der äußeren Schleife überprüfen, ob die Bedingung gesetzt ist, und dann auch von der äußeren Schleife abbrechen.

    boolean isBreakNeeded = false;
    for (int i = 0; i < some.length; i++) {
        for (int j = 0; j < some.lengthasWell; j++) {
            //want to set variable if (){
            isBreakNeeded = true;
            break;
        }
    
        if (isBreakNeeded) {
            break; //will make you break from the outer loop as well
        }
    }

1

In einigen Fällen können wir die whileSchleife hier effektiv verwenden.

Random rand = new Random();
// Just an example
for (int k = 0; k < 10; ++k) {
    int count = 0;
    while (!(rand.nextInt(200) == 100)) {
       count++;
    }

    results[k] = count;
}

1

Java hat keine Goto-Funktion wie in C ++. Dennoch gotoist ein reserviertes Schlüsselwort in Java. Sie könnten es in Zukunft implementieren. Auf Ihre Frage lautet die Antwort, dass es in Java ein sogenanntes Label gibt, auf das Sie eine continueand- breakAnweisung anwenden können . Finden Sie den Code unten:

public static void main(String ...args) {
    outerLoop: for(int i=0;i<10;i++) {
    for(int j=10;j>0;j--) {
        System.out.println(i+" "+j);
        if(i==j) {
            System.out.println("Condition Fulfilled");
            break outerLoop;
        }
    }
    }
    System.out.println("Got out of the outer loop");
}

1

Sogar das Erstellen eines Flags für die äußere Schleife und das Überprüfen, ob nach jeder Ausführung der inneren Schleife die Antwort sein kann.

So was:

for (Type type : types) {
    boolean flag=false;
    for (Type t : types2) {
        if (some condition) {
            // Do something and break...
            flag=true;
            break; // Breaks out of the inner loop
        }
    }
    if(flag)
        break;
}

1
boolean condition = false;
for (Type type : types) {
    for (int i = 0; i < otherTypes.size && !condition; i ++) {
        condition = true; // If your condition is satisfied
    }
}

Verwenden Sie conditionals Flag für , wenn Sie fertig Verarbeitung sind. Dann wird die innere Schleife nur fortgesetzt, solange die Bedingung nicht erfüllt ist. In jedem Fall wird die äußere Schleife weiter tuckern.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.