Как вырваться из вложенных циклов в Java? - PullRequest
1689 голосов
/ 20 мая 2009

У меня есть конструкция с вложенным циклом:

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

Теперь, как мне вырваться из обеих петель? Я смотрел на похожие вопросы, но ни один из них не касается конкретно Java. Я не мог применить эти решения, потому что большинство использовало gotos.

Я не хочу помещать внутренний цикл в другой метод.

Я не хочу перезапускать циклы. При разрыве я заканчиваю выполнение блока цикла.

Ответы [ 33 ]

2 голосов
/ 04 мая 2017

Демо для break, continue и label:

Ключевые слова Java break и continue имеют значение по умолчанию. Это «ближайший цикл», и сегодня, после нескольких лет использования Java, я только что понял!

Кажется, он используется редко, но полезно.

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 голосов
/ 12 сентября 2013
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;
    }
}
2 голосов
/ 13 сентября 2014

Как и предложение @ 1800 ИНФОРМАЦИЯ, используйте условие, которое разрывает внутренний цикл, как условие для внешнего цикла:

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 голосов
/ 01 апреля 2017

Если это новая реализация, вы можете попробовать переписать логику как операторы 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
    }
}

В противном случае вы можете попытаться установить флаг, когда это специальное условие произошло, и проверить наличие этого флага в каждом из ваших условий цикла.

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

ЗДЕСЬ! Таким образом, хотя простой перерыв не будет работать, его можно заставить работать с помощью continue.

Если вы просто переносите логику с одного языка программирования на Java и просто хотите, чтобы все работало, вы можете попробовать использовать метки .

1 голос
/ 24 марта 2017

В некоторых случаях мы можем эффективно использовать цикл while.

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 голос
/ 28 апреля 2013

Даже создание флага для внешнего цикла и проверка того, что после каждого выполнения внутреннего цикла может быть ответ.

Как это:

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 голос
/ 08 мая 2019

Ниже приведен пример, где оператор «break» выталкивает курсор из цикла for при выполнении условия.

public class Practice3_FindDuplicateNumber {

    public static void main(String[] args) {
        Integer[] inp = { 2, 3, 4, 3, 3 };
        Integer[] aux_arr = new Integer[inp.length];
        boolean isduplicate = false;
        for (int i = 0; i < aux_arr.length; i++) {

            aux_arr[i] = -1;

        }
        outer: for (int i = 0; i < inp.length; i++) {
            if (aux_arr[inp[i]] == -200) {
                System.out.println("Duplicate Found at index: " + i + " Carrying value: " + inp[i]);
                isduplicate = true;
                break outer;
            } else {
                aux_arr[inp[i]] = -200;
            }
        }

        for (Integer integer : aux_arr) {
            System.out.println(integer);
        }

        if (isduplicate == false) {
            System.out.println("No Duplicates!!!!!");
        } else {
            System.out.println("Duplicates!!!!!");
        }
    }

}
1 голос
/ 19 сентября 2017

Вы можете сделать следующее:

  1. установить локальную переменную на false

  2. установите эту переменную true в первом цикле, когда вы хотите разорвать

  3. тогда вы можете проверить во внешнем цикле, что если условие установлено, то также выйти из внешнего цикла.

    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
        }
    }
    
0 голосов
/ 07 мая 2013

Проверьте, не завершен ли внутренний цикл с помощью оператора if, проверив переменную внутреннего цикла. Вы также можете создать другую переменную, такую ​​как логическое значение, чтобы проверить, завершен ли внутренний цикл.

В этом примере он использует переменную внутреннего цикла, чтобы проверить, был ли он завершен:

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   
     } 
}
0 голосов
/ 11 июля 2014
boolean condition = false;
for (Type type : types) {
    for (int i = 0; i < otherTypes.size && !condition; i ++) {
        condition = true; // If your condition is satisfied
    }
}

Используйте condition в качестве флага, когда вы закончите обработку. Тогда внутренний цикл только продолжается, пока условие не было выполнено. В любом случае, внешний цикл будет продолжать chuggin '.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...