Pregunta Rompiendo bucles anidados en Java


Tengo una construcción de bucle anidado como esta:

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

Ahora, ¿cómo puedo salir de ambos bucles? He visto preguntas similares, pero ninguna concierne específicamente a Java. No pude aplicar estas soluciones porque la mayoría usaba gotos.

No quiero poner el lazo interno en un método diferente.

Actualización: No quiero volver a ejecutar los bucles, cuando rompo, terminé con la ejecución del bloque de bucle.


1539
2018-05-20 09:07


origen


Respuestas:


Al igual que otros contestadores, definitivamente preferir para poner el lazo interno en un método diferente. Esta respuesta solo muestra cómo se pueden cumplir los requisitos en la pregunta.

Puedes usar break con una etiqueta para el lazo externo. Por ejemplo:

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

Esto 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



Técnicamente, la respuesta correcta es etiquetar el bucle externo. En la práctica, si desea salir en cualquier punto dentro de un bucle interno, sería mejor que externalice el código en un método (un método estático si es necesario) y luego lo llame.

Eso pagaría por legibilidad.

El código se convertiría en algo así:

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

Coincidiendo con el ejemplo de la respuesta aceptada:

 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



Puede usar un bloque con nombre alrededor de los bucles:

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

186
2018-05-20 09:12



Nunca uso etiquetas Parece una mala práctica para entrar. Esto es lo que haría:

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



Puedes usar etiquetas:

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

79
2018-05-20 09:11



tal vez con una función?

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



Puedes usar una variable temporal:

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

Según su función, también puede salir / regresar del bucle interno:

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

15
2018-05-20 09:11