Question Rupture des boucles imbriquées en Java


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 ne pouvais pas appliquer ces solutions car les gotos les plus utilisés.

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

Mise à jour: je ne veux pas relancer les boucles, en cas de rupture je suis fini avec l'exécution du bloc en boucle.


1539
2018-05-20 09:07


origine


Réponses:


Comme d'autres répondeurs, j'aurais définitivement préférer mettre la boucle interne dans une méthode différente. Cette réponse montre simplement comment les exigences de la question peuvent être satisfaites.

Vous pouvez utiliser break avec une étiquette pour la boucle externe. 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

2080
2018-05-20 09:11



Techniquement, la bonne réponse est d'étiqueter la boucle externe. En pratique, si vous voulez quitter à n'importe quel point d'une boucle interne, vous feriez mieux d'externaliser le code dans une méthode (une méthode statique si besoin), 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; 
}

Correspondant à 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);
            }
        }
    }
}

368
2017-11-14 18:26



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

186
2018-05-20 09:12



Je n'utilise jamais d'étiquettes. Cela semble être une mauvaise pratique à adopter. 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;
        }
    }
}

112
2017-12-07 17:52



Vous pouvez utiliser des étiquettes:

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

79
2018-05-20 09:11



peut-être avec 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;
      }
    }
  }
}

32
2018-05-20 11:43



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

15
2018-05-20 09:11



Si vous n'aimez pas breakle sable gotos, vous pouvez utiliser une boucle "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;
        }
    }
}

10
2017-12-21 22:56