Comment sortir des boucles imbriquées en Java?


1819

J'ai une construction de boucle imbriquée comme ceci:

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

Maintenant, comment puis-je sortir des deux boucles? J'ai examiné des questions similaires, mais aucune ne concerne spécifiquement Java. Je n'ai pas pu appliquer ces solutions car la plupart des gotos utilisés.

Je ne veux pas mettre la boucle intérieure dans une méthode différente.

Je ne veux pas relancer les boucles. A la rupture, j'ai terminé l'exécution du bloc de boucle.

Réponses:


2427

Comme d' autres answerers, je serais certainement préfère mettre les boucles dans une autre méthode, à quel point vous pouvez simplement revenir à itérer arrêter complètement. Cette réponse montre simplement comment les exigences de la question peuvent être satisfaites.

Vous pouvez utiliser breakavec une étiquette pour la boucle extérieure. Par exemple:

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");
    }
}

Cela imprime:

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

287
Cela ne saute directement après la boucle. Essayez! Oui, l'étiquette vient avant la boucle, mais c'est parce qu'elle marque la boucle, plutôt que l'endroit où vous souhaitez sortir. (Vous pouvez également continuer avec un label.)
Jon Skeet

2
Perl autorise également son propre système d'étiquettes. Je pense que beaucoup de langages le font - cela ne me surprend guère que ce soit en Java.
Evan Carroll

9
@Evan - cette affirmation est clairement vraie - dans des langues qui promettent que c'est vrai. Mais Java ne fait pas cette promesse. Si une langue est en conflit avec vos hypothèses, il est possible que ce soient vos hypothèses qui soient en faute. Dans ce cas, je pense que vous avez toujours en partie raison - principe de la moindre surprise WRT ceux qui n'ont jamais entendu parler (ou oublié) de cette forme de break. Même alors, les exceptions sont une autre exception plus connue (désolé). Mais je serais toujours mécontent de cela si ce n'était pas évident (petites boucles, commentaire d'avertissement si le label / break n'est toujours pas assez visible).
Steve314

6
@MuhammadBabar: outerloopest une étiquette. Je ne sais pas exactement quel code vous avez essayé, mais le code dans ma réponse se compile et fonctionne très bien.
Jon Skeet

4
@NisargPatil Tout simplement parce qu'il est dans sonarLint ne fait pas une odeur de code. Cela signifie simplement qu'un développeur a ajouté cela à sonarLint avec une démangeaison personnelle à gratter, et il est plein de ces types de règles qui n'ont de sens que lorsqu'ils sont maltraités, ou parce que certains développeurs ont une croisade de haine personnelle contre eux. Les pauses et les continuations étiquetées sont une manière très élégante de décrire ce que vous voulez faire.
john16384

403

Techniquement, la bonne réponse consiste à étiqueter la boucle extérieure. En pratique, si vous souhaitez quitter à tout moment à l'intérieur d'une boucle interne, vous feriez mieux d'externaliser le code dans une méthode (une méthode statique si nécessaire), puis de l'appeler.

Cela serait payant pour la lisibilité.

Le code deviendrait quelque chose comme ça:

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

Correspond à l'exemple de la réponse acceptée:

 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
Parfois, vous utilisez plusieurs variables locales qui sont en dehors de la boucle interne, les passer toutes peuvent sembler maladroites.
2011 le plus chaud

1
Alors, comment cette solution est-elle censée imprimer "Terminé" comme dans la réponse acceptée?
JohnDoe

1
@JohnDoe vous l'appelez puis vous imprimez System.out.println ("done"); essayer {} enfin {} dans la méthode de recherche est également une option.
Zo72

2
C'est une meilleure pratique, je suppose, mais que se passe-t-il si vous voulez continuer au lieu de vous interrompre? Les étiquettes prennent en charge aussi bien (ou mal!) Mais je ne sais pas comment convertir cette logique pour continuer.
Rob Grant

@RobertGrant Si vous souhaitez continuer au lieu de rompre, déplacez la boucle externe en dehors de la loopméthode et revenez de la méthode pour continuer.
Muhd

215

Vous pouvez utiliser un bloc nommé autour des boucles:

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

40
Vous n'avez pas besoin de créer un nouveau bloc pour utiliser une étiquette.
Jon Skeet

81
Non, mais cela rend l'intention beaucoup plus claire. Voir le premier commentaire sur la réponse acceptée.
Bombe

2
ce n'est pas réellement un bloc nommé, après l'étiquette, vous pouvez écrire n'importe quelle expression Java comme sans étiquette, name: if(...){...}fait la condition nommée? :)
La VloZ Merrill

4
Cette construction a un gros avantage sur l'étiquetage fordirect. Vous pouvez ajouter du code avant le dernier }qui sera exécuté uniquement si la condition n'a jamais été remplie.
Florian F

2
Il s'agit d'un bloc nommé et non d'une boucle nommée. Vous ne pouviez pas dans cette boucle "continuer la recherche"; qui est totalement une syntaxe légale si la boucle est nommée recherche. Vous pouvez le casser, mais vous ne pouvez pas le continuer.
Tatarize

132

Je n'utilise jamais d'étiquettes. Cela semble être une mauvaise pratique. Voici ce que je ferais:

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
Cela ne devrait-il pas être à la && !finishedplace || !finished? Et pourquoi alors utiliser breakdu tout et ne pas utiliser aussi && !finishedpour la boucle intérieure?
Gandalf

4
J'utilise breakpour pouvoir sortir arbitrairement de la boucle. S'il y a du code après ce ifbloc, vous pouvez le faire breakavant son exécution. Mais vous avez raison &&. A corrigé.
Elle Mundy

2
belle solution! c'est exactement comment je le ferais dans la pratique si le mettre dans une fonction supplémentaire n'est pas préférable pour une raison quelconque.
benroth

6
Il y a un problème potentiel s'il y a une logique après la boucle interne ... qui continuera à être exécutée et la boucle externe ne se
cassera

7
Je ne comprends pas pourquoi on devrait le faire comme ça. Les personnes travaillant avec du code devraient pouvoir utiliser toutes les fonctionnalités d'un langage. Je comprends qu'il est important d'écrire du code que les autres peuvent comprendre, mais pas en restreignant l'utilisation des outils officiels fournis par un langage et en trouvant des solutions de contournement pour la même fonctionnalité. Ou vouliez-vous dire autre chose par "mauvaise pratique"?
codepleb

107

Vous pouvez utiliser des étiquettes:

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

4
Ayez un +1 de moi. Simple, au point, répond à la question. On ne peut pas vous accuser de répéter une réponse existante parce que vous avez répondu en même temps.
Heimdall

40

Utilisez une fonction:

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

Vous pouvez utiliser une variable temporaire:

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
         }
    }
}

Selon votre fonction, vous pouvez également quitter / revenir de la boucle interne:

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

7
Je trouve cette façon un peu encombrée.
boutta

11
Un contrôle de condition supplémentaire à chaque fois dans la boucle? Non merci.
ryandenki

15

Si vous n'aimez pas les breaks et les gotos, vous pouvez utiliser une boucle for "traditionnelle" à la place du for-in, avec une condition d'abandon supplémentaire:

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
Ne convient pas pour chaque boucle.
John McClane

1
@JohnMcClane Et vous envoyez du spam sur de nombreuses réponses à une question de plus de 9 ans parce que ...?
Quintec

12

J'avais besoin de faire une chose similaire, mais j'ai choisi de ne pas utiliser la boucle for améliorée pour le faire.

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;
        }
    }
}

Je ne trouve pas cool d'itérer tous les articles après que la condition soit brisée. J'ajouterais donc une pause dans le cas contraire.
boutta

@boutta Je ne sais pas comment vous arrivez à cette conclusion. Une fois la condition remplie, les deux boucles sont fermées.
Swifty McSwifterton

OK, je n'ai pas eu la partie avec la manipulation du var 's'. Mais je trouve ce genre de mauvais style car s représente la taille. Ensuite, je préfère la réponse de ddyer avec des variables explicites: stackoverflow.com/a/25124317/15108
boutta

@boutta Vous pouvez passer sà une valeur inférieure à iou changer ià une valeur supérieure ou égale à s, les deux devraient faire l'affaire. Vous avez raison de changer s, car il peut être utilisé ailleurs plus tard, mais le changement ine nuira pas, vous garantira simplement que le premier forne continuera pas à boucler.
Zsolti

9

Je préfère ajouter une "sortie" explicite aux tests de boucle. Il indique clairement à tout lecteur occasionnel que la boucle peut se terminer plus tôt.

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

Ne convient pas pour chaque boucle.
John McClane

8

StreamSolution Java 8 :

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 et toujours utile pour les autres utilisateurs, donc les nouvelles méthodes et solutions sont toujours les bienvenues
Andrei Suvorkov

Wow, c'est moche.
DS.

7

Habituellement, dans de tels cas, cela entre dans le cadre d'une logique plus significative, disons quelques recherches ou manipulations sur certains des objets `` pour '' itérés en question, donc j'utilise généralement l'approche fonctionnelle:

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;
}

Contre majeur:

  • environ deux fois plus de lignes
  • plus de consommation de cycles de calcul, ce qui signifie qu'il est plus lent du point de vue algorithmique
  • plus de travail de dactylographie

Les avantages:

  • le rapport plus élevé à la séparation des préoccupations en raison de la granularité fonctionnelle
  • le ratio plus élevé de réutilisation et de contrôle de la logique de recherche / manipulation sans
  • les méthodes ne sont pas longues, donc elles sont plus compactes et plus faciles à comprendre
  • ratio de lisibilité supérieur

Il s'agit donc simplement de gérer le cas via une approche différente.

Fondamentalement, une question à l'auteur de cette question: que pensez-vous de cette approche?


6

Vous pouvez interrompre toutes les boucles sans utiliser d'étiquette: et de drapeaux.

C'est juste une solution délicate.

Ici condition1 est la condition qui est utilisée pour rompre les boucles K et J.Et condition2 est la condition qui est utilisée pour rompre les boucles K, J et I.

Par exemple:

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
Comment l'utiliser avec des boucles for-each? ;)
Willi Mentzel

5
Cela ne fonctionne pas si vous avez une condition de boucle plus sophistiquée, comme list.size ()> 5. De plus, c'est vraiment juste un hack. C'est difficile à lire et mauvaise pratique!
Neuron

Il est sujet aux erreurs. Imaginez que vous avez changé la boucle intérieure pour (int k = 0; k < 10; k++)vous n'a pas résolu tous les k = 9à k = 10. Vous pourriez entrer dans une boucle infinie.
Florian F

5

Le concept de rupture étiquetée est utilisé pour séparer les boucles imbriquées en java, en utilisant la rupture étiquetée, vous pouvez interrompre l'imbrication des boucles à n'importe quelle position. Exemple 1:

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

supposons qu'il y ait 3 boucles et que vous vouliez terminer la boucle3: Exemple 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

S'il se trouve dans une fonction, pourquoi ne le renvoyez-vous pas:

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

Je préfère ce modèle. Cela m'a souvent amené à séparer les boucles en une fonction distincte. Mon code a toujours été meilleur après cela, donc pour cette raison, j'aime vraiment cette réponse.
Bill K

4

Meilleure méthode et facile ..

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
Ces exemples de rupture ne sont pas très utiles, car même sans l'étiquette, ils se briseraient au même point. De plus, il est toujours agréable d'avoir du code que vous pouvez réellement exécuter, ce qui n'est pas le cas avec votre code, car la boucle interne ne peut jamais être atteinte.
Neuron

J'allais taper la même chose. Les étiquettes sont quelque peu inutiles dans ce cas.
Taslim Oseni

4

Approche plutôt inhabituelle mais en termes de longueur de code ( pas de performances ), c'est la chose la plus simple que vous pourriez faire:

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

Une autre solution, mentionnée sans exemple (elle fonctionne en fait dans le code prod).

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.
}

Bien sûr, il BreakLoopExceptiondoit être interne, privé et accéléré sans trace de pile:

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

1
Il a été mentionné en fait, dans une réponse obtenant -23 votes ... stackoverflow.com/a/886980/2516301 . Il fera le travail, mais c'est une très mauvaise pratique de programmation ...
vefthym

En effet. cependant, j'ai vu un tel code hérité - des boucles imbriquées à 4 niveaux avec plusieurs conditions de rupture. et il était plus lisible avec des exceptions plutôt qu'avec du code en ligne. -23 votes est principalement une note émotionnelle, mais oui - cette approche doit être utilisée avec prudence.
ursa

1
Il aurait été encore plus lisible s'il avait été divisé en un appel de fonction séparé avec un retour central. Souvent rendu encore meilleur par un petit refactor, il est donc logique en tant que fonction autonome (souvent réutilisable).
Bill K

2

for (int j = 0; j < 5; j++) //inner loopdoit être remplacé par for (int j = 0; j < 5 && !exitloops; j++).

Ici, dans ce cas, les boucles imbriquées complètes doivent être sorties si la condition est True. Mais si nous utilisons exitloopsuniquement à la partie supérieureloop

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

Ensuite, la boucle interne se poursuivra, car il n'y a pas d'indicateur supplémentaire qui avertit cette boucle interne de quitter.

Exemple: si i = 3et j=2alors la condition est false. Mais dans la prochaine itération de la boucle intérieure, la j=3 condition (i*j)devient 9ce qui est, truemais la boucle intérieure se poursuivra jusqu'à jdevenir 5.

Donc, il doit aussi utiliser exitloopsles boucles intérieures.

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

Comme la suggestion @ 1800 INFORMATION, utilisez la condition qui rompt la boucle intérieure comme condition sur la boucle extérieure:

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

S'il s'agit d'une nouvelle implémentation, vous pouvez essayer de réécrire la logique en tant qu'instructions if-else_if-else.

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
    }
}

Sinon, vous pouvez essayer de définir un indicateur lorsque cette condition spéciale s'est produite et vérifier cet indicateur dans chacune de vos conditions de boucle.

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.
}

ICI! Ainsi, même si une simple pause ne fonctionnera pas, elle peut être effectuée en utilisant continue.

Si vous portez simplement la logique d'un langage de programmation vers Java et que vous voulez simplement faire fonctionner la chose, vous pouvez essayer d'utiliser des étiquettes .


2

Demo pour break, continueet label:

Mots break- clés Java etcontinue ont une valeur par défaut. C'est la "boucle la plus proche", et aujourd'hui, après quelques années d'utilisation de Java, je viens de la comprendre!

Il semble utilisé rare, mais utile.

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

Démo

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

1

Vous pouvez effectuer les opérations suivantes:

  1. définir une variable locale sur false

  2. définissez cette variable truedans la première boucle, lorsque vous voulez rompre

  3. vous pouvez ensuite vérifier dans la boucle externe, que si la condition est définie, puis rompre également avec la boucle externe.

    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

Dans certains cas, nous pouvons utiliser la whileboucle efficacement ici.

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 n'a pas de fonction goto comme en C ++. Mais encore, gotoest un mot-clé réservé en Java. Ils pourraient l'appliquer à l'avenir. Pour votre question, la réponse est qu'il existe quelque chose appelé étiquette en Java auquel vous pouvez appliquer une instruction continueand break. Trouvez le code ci-dessous:

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

Même la création d'un indicateur pour la boucle externe et la vérification qu'après chaque exécution de la boucle interne peut être la réponse.

Comme ça:

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
    }
}

À utiliser conditioncomme indicateur lorsque vous avez terminé le traitement. Ensuite, la boucle intérieure continue uniquement tant que la condition n'est pas remplie. Quoi qu'il en soit, la boucle extérieure continuera de chuggin '.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.