salir - while anidado java figuras geometricas




¿Cómo salir de los bucles anidados en Java? (20)

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 se refiere específicamente a Java. No pude aplicar estas soluciones porque la mayoría usa gotos.

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

Actualización: no quiero volver a ejecutar los bucles, cuando termine la ruptura, he terminado con la ejecución del bloque de bucle.


Al igual que en la sugerencia de información de 1800, use la condición que rompe el bucle interno como condición en el bucle externo:

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

Como otros respondedores, definitivamente preferiría poner el bucle interno en un método diferente. Esta respuesta solo muestra cómo se pueden cumplir los requisitos de la pregunta.

Puede utilizar break con una etiqueta para el bucle exterior. 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

Enfoque bastante inusual, pero en términos de longitud de código ( no de rendimiento ), esto es lo más fácil que podría hacer:

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

Incluso creando una bandera para el bucle externo y verificando que después de cada ejecución del bucle interno puede ser la respuesta.

Me gusta esto :

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

Método mejor y fácil.

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

Necesitaba hacer algo similar, pero elegí no usar el bucle mejorado para hacerlo.

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

Otra solución, mencionada sin ejemplo (realmente funciona en código de producto).

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

Por supuesto, la BreakLoopException debe ser interna, privada y acelerada con no-stack-trace:

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

Para algunos casos, podemos usar el bucle while efectivamente aquí.

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

Prefiero agregar una "salida" explícita a las pruebas de bucle. Le deja claro a cualquier lector casual que el bucle puede terminar antes.

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

Puedes hacer lo siguiente:

  1. establecer una variable local en false

  2. establece esa variable true en el primer bucle, cuando quieres romper

  3. luego puede verificar en el bucle externo, que si la condición está establecida, entonces también se rompe desde el bucle externo.

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

Puedes usar etiquetas:

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

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

Quería responder a this pregunta, pero me marcaron como un duplicado que también me impide publicar. Así que publicarlo aquí en su lugar!

Si se trata de una nueva implementación, puede intentar volver a escribir la lógica como si fuesen las instrucciones 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
    }   
}

De lo contrario, puede intentar establecer una bandera cuando haya ocurrido esa condición especial y verificar esa bandera en cada una de sus condiciones de bucle.

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) { // things below will not be executed
        continue;
    }

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

HERE! So, while a simple break will not work, it can be made to work using continue.

Si simplemente estás portando la lógica de un lenguaje de programación a Java y solo quieres que funcione, puedes intentar usar labels


Si está dentro de alguna función, ¿por qué no lo devuelves?

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

Solo usa la etiqueta para romper los bucles internos

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

Solución Java 8 Stream :

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**/);

Utilice etiquetas.

INNER:for(int j = 0; j < numbers.length; j++) {
    System.out.println("Even number: " + i + ", break  from INNER label");
    break INNER;
}

Consulte este artículo


Verifique si el bucle interno se sale con una sentencia if, verificando la variable del bucle interno. También puede crear otra variable como un booleano para verificar si se sale del bucle interno.

En este ejemplo, utiliza la variable del bucle interno para verificar si se ha salido:

int i, j;
for(i = 0; i < 7; i++){

for(j = 0; j < 5; j++) {

     if (some condition) {
         // Do something and break...
         break; // Breaks out of the inner loop
     }
}
     if(j < 5){    // Checks if inner loop wasn't finished
     break;    // Breaks out of the outer loop   
     } 
}

for (int j = 0; j < 5; j++) //inner loop debe reemplazarse por for (int j = 0; j < 5 && !exitloops; j++) .

Aquí, en este caso, los bucles anidados completos deben salir si la condición es True . Pero si usamos exitloops solo para el loop superior

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

Luego, el bucle interno continuará, porque no hay un indicador adicional que notifique a este bucle interno para salir.

Ejemplo: si i = 3 y j=2 entonces la condición es false . Pero en la siguiente iteración del bucle interno j=3 entonces la condición (i*j) convierte en 9 cual es true pero el bucle interno continuará hasta que j convierta en 5 .

Por lo tanto, debe usar exitloops para los bucles internos también.

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

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






loops