20

Как выйти из вложенных циклов в Java?

22

У меня есть конструкция вложенного цикла, выглядящая примерно так:

for (Type type : types) {
    for (Type t : types2) {
         if (условие) {
             // Выполняю какие-то действия и выхожу...
             break; // Выходит из внутреннего цикла
         }
    }
}

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

Я не хочу выносить внутренний цикл в отдельный метод.

Мне не нужно возвращаться из циклов. При выходе я завершаю выполнение блока циклов.

5 ответ(ов)

27

Как и другие отвечающие, я определённо предпочёл бы вынести циклы в отдельный метод, в котором можно просто использовать оператор return, чтобы полностью остановить итерацию. Этот ответ демонстрирует, как требования из вопроса могут быть выполнены.

Вы можете использовать оператор break с меткой для внешнего цикла. Например:

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

Этот код выводит:

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
4

Технически правильный ответ заключается в том, что следует использовать метку для внешнего цикла. На практике, если вам нужно выйти из любой точки внутреннего цикла, будет логичнее выделить код в отдельный метод (при необходимости — статический метод) и затем просто его вызывать.

Это повысит читаемость кода.

Код может выглядеть примерно так:

private static String search(...) {
    for (Type type : types) {
        for (Type t : types2) {
            if (someCondition) {
                // Выполнить что-то и выйти...
                return search;
            }
        }
    }
    return null; 
}

С учетом примера из принятого ответа:

public class Test {
    public static void main(String[] args) {
        loop();
        System.out.println("Готово");
    }

    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("Выход из цикла");
                    return;
                }
                System.out.println(i + " " + j);
            }
        }
    }
}

Использование методов для управления потоком исполнения сделает ваш код более структурированным и удобным для понимания.

2

Вы можете использовать именованный блок вокруг циклов:

search: {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Выполните какое-то действие и выйдите из блока...
                break search;
            }
        }
    }
}

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

1

Я никогда не использую метки. Это кажется плохой практикой. Вот что бы я делал:

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

Используя переменную-флаг, мы можем легко контролировать выполнение любого количества циклов. Просто нужно следить за значением этого флага в условии цикла, как сделано в основном цикле: i < 5 && !finished.

1

Вы можете использовать метки в языке программирования Java следующим образом:

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

В данном примере мы создаём метку label1, которая позволяет прерывать внешний цикл for из внутреннего цикла. Команда break label1; завершает выполнение цикла, помеченного меткой label1, и управление передаётся к первой строке после этого цикла. Использование меток может быть полезно для управления вложенными циклами, особенно если нужно выйти из нескольких уровней вложенности одновременно.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь