Как вырваться из вложенных циклов в Java?

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

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

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

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

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

20.05.2009 09:07:43
30 ОТВЕТОВ
РЕШЕНИЕ

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

Вы можете использовать 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
2398
5.12.2018 07:27:30
Это действительно сразу после цикла. Попробуй это! Да, метка идет перед циклом, но это потому, что она маркирует цикл, а не место, в которое вы хотите выйти. (Вы также можете продолжить с лейблом.)
Jon Skeet 20.05.2009 09:15:25
Perl также разрешает это своей собственной системой меток. Я думаю, что это делают многие языки - меня вряд ли удивит, что это на Java.
Evan Carroll 6.12.2011 22:53:41
@Evan - это утверждение явно верно - на языках, которые обещают, что это правда. Но Java не дает этого обещания. Если язык противоречит вашим предположениям, возможно, виноваты именно ваши предположения. В этом случае, я думаю, вы все еще отчасти правы - принцип наименьшего удивления для многих тех, кто никогда не слышал (или не забывал) об этой форме break. Даже тогда исключения являются еще одним более известным исключением (извините). Но я все еще был бы недоволен этим, если бы это не было очевидно (небольшие циклы, предупреждающий комментарий, если метка / разрыв все еще недостаточно видны).
Steve314 7.12.2011 00:40:22
@MuhammadBabar: outerloopэто лейбл. Я не знаю точно, какой код вы пробовали, но код в моем ответе компилируется и работает просто отлично.
Jon Skeet 2.02.2015 10:47:13
@NisargPatil Только потому, что он в sonarLint, не делает его запахом кода. Это просто означает, что был разработчик, который добавил это в sonarLint с личным желанием поцарапать, и он полон таких правил, которые имеют смысл только при злоупотреблении или потому, что у какого-то разработчика есть личный крестовый поход против них. Помеченные разрывы и продолжения - это очень элегантный способ описать, что вы хотите сделать.
john16384 8.02.2019 16:52:51

Вы можете использовать метки:

label1: 
for (int i = 0;;) {
    for (int g = 0;;) {
      break label1;
    }
}
106
20.04.2018 16:30:26
+1 от меня. Просто, к сути, отвечает на вопрос. Не может быть обвинен в повторении существующего ответа, потому что вы ответили одновременно.
Heimdall 7.12.2018 16:31:28

Вы можете использовать временную переменную:

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

В зависимости от вашей функции вы также можете выйти / вернуться из внутреннего цикла:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             return;
         }
    }
}
20
20.05.2009 09:11:59
Я нахожу этот путь беспорядочным.
boutta 20.05.2009 09:19:03
Дополнительная проверка состояния каждый раз через цикл? Нет, спасибо.
ryandenki 7.12.2011 04:29:52

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

search: {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Do something and break...
                break search;
            }
        }
    }
}
214
20.05.2009 09:12:12
Вам не нужно создавать новый блок, чтобы использовать метку.
Jon Skeet 20.05.2009 09:13:19
Нет, но это проясняет намерение. Смотрите первый комментарий о принятом ответе.
Bombe 20.05.2009 09:24:07
это на самом деле не именованный блок, после метки вы можете написать любое выражение Java как без метки, name: if(...){...}делает ли названное условие? :)
La VloZ Merrill 21.04.2016 21:18:58
Эта конструкция имеет большое преимущество по сравнению с forпрямой маркировкой . Вы можете добавить код перед последним, }который будет выполнен, только если условие никогда не выполнялось.
Florian F 25.08.2018 20:24:54
Это именованный блок, а не именованный цикл. Вы не могли бы внутри этого цикла "продолжить поиск"; который является полностью допустимым синтаксисом, если цикл называется поиском. Вы можете сломать это, но вы не можете продолжать это.
Tatarize 16.12.2018 18:29:12

Используйте функцию:

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;
      }
    }
  }
}
40
5.01.2019 09:22:36

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

Это окупится за удобочитаемость.

Код станет примерно таким:

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

Соответствие примеру для принятого ответа:

 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);
            }
        }
    }
}
402
3.06.2012 10:31:41
Иногда вы используете несколько локальных переменных, которые находятся вне внутреннего цикла, передавая их все может показаться неуклюжим.
Haoest 7.12.2011 01:15:54
Так как же это решение должно печатать «Готово», как в принятом ответе?
JohnDoe 7.12.2011 10:02:29
@John. Вы называете это, а затем печатаете System.out.println («сделано»); try {} finally {} в методе поиска также является опцией.
Zo72 16.05.2012 14:32:09
Я полагаю, что это лучшая практика, но что произойдет, если вы захотите продолжить, а не сломаться? Метки поддерживают одинаково хорошо (или плохо!), Но я не уверен, как преобразовать эту логику для продолжения.
Robert Grant 25.10.2013 10:01:10
@RobertGrant Если вы хотите продолжить вместо прерывания, переместите внешний цикл за пределы loopметода и вернитесь из метода для продолжения.
Muhd 1.08.2016 20:35:47

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

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;
        }
    }
}
132
4.08.2014 17:18:10
Разве это не должно быть && !finishedвместо || !finished? А зачем тогда breakвообще использовать и не использовать && !finishedдля внутреннего цикла тоже?
Gandalf 12.07.2013 11:29:05
Я использую, breakчтобы иметь возможность произвольно выйти из цикла. Если после этого ifблока есть код , вы можете breakвыполнить его до выполнения. Но ты прав &&. Починил это.
Elle Mundy 29.07.2013 16:44:54
отличное решение! это именно то, как я бы сделал это на практике, если по какой-то причине использование дополнительной функции нежелательно.
benroth 10.12.2013 19:50:02
Существует потенциальная проблема, если после внутреннего цикла есть какая-то логика ... которая будет продолжать выполняться, а внешний цикл прерывается только тогда, когда начинается новая итерация ...
Karthik Karuppannan 3.02.2016 15:58:47
Я не понимаю, почему нужно так делать. Люди, работающие с кодом, должны иметь возможность использовать все возможности языка. Я понимаю, что важно писать код, понятный другим, но не ограничивая использование официальных инструментов, предоставляемых языком, и находить обходные пути для той же функциональности. Или вы имели в виду что-то еще под "плохой практикой"?
codepleb 11.10.2016 09:32:56

Мне нужно было сделать аналогичную вещь, но я решил не использовать расширенный цикл for, чтобы сделать это.

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;
        }
    }
}
12
10.11.2016 08:54:50
Я не считаю крутым повторять все элементы после того, как условие нарушено. Таким образом, я бы добавил перерыв в другом случае.
boutta 29.01.2016 07:58:05
@boutta Я не уверен, как вы пришли к такому выводу. Как только условие выполнено, оба цикла завершаются.
Swifty McSwifterton 31.07.2016 16:53:29
Хорошо, я не получил часть с манипуляциями с 's' var. Но я нахожу такой плохой стиль, так как s представляет размер. Тогда я предпочитаю ответ от ddyer с явными переменными: stackoverflow.com/a/25124317/15108
boutta 10.11.2016 08:56:46
@boutta Вы можете изменить sзначение, которое меньше iили изменить iна значение, большее или равное s, оба должны сделать свое дело. Вы правы насчет изменения s, потому что позже его можно будет использовать в другом месте, но изменение iне повредит, просто убедится, что первое forне продолжит цикл.
Zsolti 27.09.2017 12:44:36

Вы просто используете ярлык для разрыва внутренних петель

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
25.10.2012 08:39:43

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

Нравится:

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
5.01.2019 09:23:33

Проверьте, завершен ли внутренний цикл с помощью оператора 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
7.05.2013 18:57:20
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;
    }
}
4
11.09.2013 22:14:59

Если вам не нравятся breaks и gotos, вы можете использовать «традиционный» цикл for вместо for-in с дополнительным условием прерывания:

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;
        }
    }
}
15
21.12.2013 22:56:34
Не подходит для петель foreach.
John McClane 5.12.2018 00:00:45
@JohnMcClane И вы спамите это на многих ответах на вопрос 9+ лет, потому что ...?
Quintec 7.12.2018 01:03:29

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

Это просто хитрое решение.

Здесь условие 1 - это условие, которое используется для разрыва цикла K и J. И условие 2 - это условие, которое используется для разрыва цикла K, J и I.

Например:

public class BreakTesting {
    public static void main(String[] args) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                for (int k = 0; k < 9; k++) {
                    if (condition1) {
                        System.out.println("Breaking from Loop K and J");
                        k = 9;
                        j = 9;
                    }
                    if (condition2) {
                        System.out.println("Breaking from Loop K, J and I");
                        k = 9;
                        j = 9;
                        i = 9;
                    }
                }
            }
        }
        System.out.println("End of I , J , K");
    }
}
6
25.04.2015 22:44:38
Как бы я использовал это для циклов for-each? ;)
Willi Mentzel 4.07.2015 11:18:40
Это не работает, если у вас более сложное условие цикла, например list.size ()> 5. И это действительно просто взлом. Трудно читать и плохая практика!
Neuron 26.10.2015 03:06:30
Это подвержено ошибкам. Представьте, что вы изменили внутренний цикл на (int k = 0; k < 10; k++)и вы не исправили все k = 9на k = 10. Вы можете попасть в бесконечный цикл.
Florian F 25.08.2018 20:07:26

Используйте ярлыки.

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

Обратитесь к этой статье

4
20.04.2018 16:34:23
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 '.

1
5.01.2019 09:24:30

Я предпочитаю добавить явный «выход» к тестам цикла. Любой случайный читатель дает понять, что цикл может закончиться рано.

boolean earlyExit = false;
for(int i = 0 ; i < 10 && !earlyExit; i++) {
     for(int j = 0 ; i < 10 && !earlyExit; j++) { earlyExit = true; }
}
9
20.04.2018 16:33:33
Не подходит для петель foreach.
John McClane 4.12.2018 23:39:54

Как и предложение @ 1800 INFORMATION, используйте условие, которое разрывает внутренний цикл, в качестве условия на внешний цикл:

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
20.04.2018 16:33:07

Еще одно решение, упомянутое без примера (на самом деле оно работает в коде prod).

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

Конечно, он BreakLoopExceptionдолжен быть внутренним, частным и ускоренным без отслеживания стека:

private static class BreakLoopException extends Exception {
    @Override
    public StackTraceElement[] getStackTrace() {
        return new StackTraceElement[0];
    }
}
4
20.04.2018 17:47:54
Это было упомянуто на самом деле, в ответ набрав -23 голоса ... stackoverflow.com/a/886980/2516301 . Это сделает работу, но это очень плохая практика программирования ...
vefthym 10.10.2014 14:09:14
верно. однако я видел такой унаследованный код - четырехуровневые вложенные циклы с несколькими нарушающими условиями. и это было более читабельным с исключениями, а не с встроенным кодом. -23 голоса - это в основном эмоциональный рейтинг, но да - такой подход следует использовать осторожно.
ursa 10.10.2014 14:22:38
Это было бы еще более читабельным, если бы он был разбит на отдельный вызов функции с возвратом по центру. Часто делается даже лучше с помощью небольшого рефакторинга, поэтому он имеет смысл как отдельная (часто многократно используемая) функция.
Bill K 2.12.2017 00:37:25

Довольно необычный подход, но с точки зрения длины кода ( не производительности ) это самое простое, что вы можете сделать:

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
    }
}
4
20.04.2018 16:32:09

Лучший и простой метод ..

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;
     }
}
4
20.04.2018 16:31:33
Эти примеры взлома не очень полезны, потому что даже без ярлыка они будут ломаться в одной точке. Кроме того, всегда приятно иметь код, который вы на самом деле можете выполнить, чего нельзя сказать о вашем коде, поскольку внутренняя петля никогда не может быть достигнута.
Neuron 26.10.2015 03:05:03
Я собирался напечатать то же самое. Этикетки в этом случае несколько бесполезны.
Taslim Oseni 12.01.2018 10:36:42

Обычно в таких случаях это входит в сферу более значимой логики, скажем, некоторого поиска или манипулирования некоторыми итеративными объектами for, о которых идет речь, поэтому я обычно использую функциональный подход:

public Object searching(Object[] types) { // Or manipulating
    List<Object> typesReferences = new ArrayList<Object>();
    List<Object> typesReferences2 = new ArrayList<Object>();

    for (Object type : typesReferences) {
        Object o = getByCriterion(typesReferences2, type);
        if(o != null) return o;
    }
    return null;
}

private Object getByCriterion(List<Object> typesReferences2, Object criterion) {
    for (Object typeReference : typesReferences2) {
        if(typeReference.equals(criterion)) {
             // here comes other complex or specific logic || typeReference.equals(new Object())
             return typeReference;
        }
    }
    return null;
}

Основные минусы:

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

Плюсы:

  • более высокое отношение к разделению интересов из-за функциональной детализации
  • более высокий коэффициент повторного использования и управления поиском / манипулированием логикой без
  • методы не длинные, поэтому они более компактны и их легче понять
  • более высокий коэффициент читаемости

Так что это просто обработка дела с помощью другого подхода.

В основном вопрос к автору этого вопроса: что вы думаете об этом подходе?

7
21.07.2019 07:11:27

Я чувствую, что использование меток делает код очень похожим на оператор goto. Это всего лишь мысль.

Вместо этого бросьте исключение во внутренний forцикл и инкапсулируйте два цикла forс помощью блока try catch.

Что-то вроде

try {
  // ...
  for(Object outerForLoop : objectsOuter) {
     // ...
     for (Object innerForLoop : objectsInner) {
        // ...
        if (isConditionTrue)
             throw new WrappedException("With some useful message. Probably some logging as well.");
     }
  }
  catch (WrappedException) {
        // Do something awesome or just don't do anything to swallow the exception.
  }

Просто мысль. Я предпочитаю этот код, так как он дает мне лучшую возможность ведения журналов (как это слово) для меня, когда он запускается в производство или что-то в этом роде.

-9
5.01.2019 09:28:57
Использование исключений для потока управления не совсем лучший метод. Так что нет, это не вариант.
boutta 1.04.2016 06:42:49
@boutta, что заставляет тебя так думать?
Neuron 20.04.2018 16:30:02
Много чтения и мнения некоторых широко доверенных людей, таких как дядя Боб или Мартин Фаулер.
boutta 22.04.2018 13:18:49
Я знаю , что этот вопрос для Явы специально , но некоторые люди приняли решение сделать это в дизайне языка , это именно то , что в Python StopIterationдля
Alvaro 29.04.2019 13:30:07

for (int j = 0; j < 5; j++) //inner loopследует заменить на for (int j = 0; j < 5 && !exitloops; j++).

Здесь, в этом случае завершенные вложенные циклы должны быть завершены, если условие выполнено True. Но если мы используем exitloopsтолько верхнийloop

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

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

Пример: если i = 3и j=2тогда условие false. Но в следующей итерации внутреннего цикла , j=3 то условие (i*j)стало 9что , trueно внутренний цикл будет продолжаться до jстать 5.

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

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);
    }
}
2
20.04.2018 16:28:31

Если это внутри какой-то функции, почему бы вам просто не вернуть ее:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
            return value;
         }
    }
}
4
25.08.2016 11:25:58
Я предпочитаю эту модель. Это часто заставляло меня разбивать петли на отдельные функции. Мой код всегда был лучше после этого, поэтому мне очень нравится этот ответ.
Bill K 2.12.2017 00:34:01

В некоторых случаях мы можем 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
20.04.2018 16:28:15

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

2
5.01.2019 09:31:53

Демо для 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
5.01.2019 09:35:03

StreamРешение Java 8 :

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**/);
8
20.04.2018 17:46:58
@ Tvde1 и все еще полезен для других пользователей, поэтому всегда приветствуются новые методы и решения
Andrei Suvorkov 16.04.2019 04:32:46
Вау, это безобразно
DS. 19.12.2019 14:01:28

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

  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
        }
    }
1
20.04.2018 16:26:48