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

Я бы сделал это, используя комбинацию файлов cookie и флеш-файлов. Создайте GUID и сохраните его в файле cookie. Если файл cookie не существует, попробуйте прочитать его из файла cookie. Если он все еще не найден, создайте его и напишите в файл cookie. Таким образом, вы можете использовать один и тот же идентификатор GUID в браузерах.

1705
задан Peter Mortensen 5 January 2019 в 09:21
поделиться

21 ответ

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

Вы можете использовать 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
2328
ответ дан 22 November 2019 в 20:09
поделиться

Я чувствую, что использование меток делает код очень похожим на оператор 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.
  }

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

-8
ответ дан Peter Mortensen 5 January 2019 в 09:21
поделиться

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

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
ответ дан boutta 5 January 2019 в 09:21
поделиться

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

  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
ответ дан Lonely Neuron 5 January 2019 в 09:21
поделиться

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

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
ответ дан Lonely Neuron 5 January 2019 в 09:21
поделиться

Если вам не нравятся break s и goto s, вы можете использовать «традиционный» цикл 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;
        }
    }
}
12
ответ дан zord 5 January 2019 в 09:21
поделиться

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

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;
         }
    }
}
16
ответ дан Miguel Ping 5 January 2019 в 09:21
поделиться

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

label1: 
for (int i = 0;;) {
    for (int g = 0;;) {
      break label1;
    }
}
94
ответ дан Lonely Neuron 5 January 2019 в 09:21
поделиться

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

search: {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Do something and break...
                break search;
            }
        }
    }
}
206
ответ дан Joey 5 January 2019 в 09:21
поделиться

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

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

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

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);
            }
        }
    }
}
383
ответ дан Blundell 5 January 2019 в 09:21
поделиться

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**/);
8
ответ дан Lonely Neuron 5 January 2019 в 09:21
поделиться

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
ответ дан Lonely Neuron 5 January 2019 в 09:21
поделиться

Мне нужно было сделать похожую вещь, но я решил не использовать расширенный цикл 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;
        }
    }
}
11
ответ дан boutta 5 January 2019 в 09:21
поделиться

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

boolean earlyExit = false;
for(int i = 0 ; i < 10 && !earlyExit; i++) {
     for(int j = 0 ; i < 10 && !earlyExit; j++) { earlyExit = true; }
}
9
ответ дан Lonely Neuron 5 January 2019 в 09:21
поделиться

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

Как это:

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
ответ дан Peter Mortensen 5 January 2019 в 09:21
поделиться

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

loop1:
 for(int i= 0; i<6; i++){
    for(int j=0; j<5; j++){
          if(i==3)
            break loop1;
        }
    }

предположим, что есть 3 цикла, и вы хотите завершить цикл 3: Пример 2:

loop3: 
for(int i= 0; i<6; i++){
loop2:
  for(int k= 0; k<6; k++){
loop1:
    for(int j=0; j<5; j++){
          if(i==3)
            break loop3;
        }
    }
}
4
ответ дан Bishal Jaiswal 5 January 2019 в 09:21
поделиться

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

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;
        }
    }
}
125
ответ дан dabluck 5 January 2019 в 09:21
поделиться

Обычно в таких случаях это входит в сферу более значимой логики, скажем, некоторого поиска или манипулирования некоторыми итеративными объектами 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;
}

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

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

Плюсы:

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

Так что это просто обработка случай через другой подход.

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

6
ответ дан Oleksii Kyslytsyn 5 January 2019 в 09:21
поделиться

Демонстрация

public static void main(String[] args) {
    outer:
    while (true) {
        while (true) {
            break outer;
        }
    }
}
2
ответ дан 22 November 2019 в 20:09
поделиться

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

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;
      }
    }
  }
}
38
ответ дан 22 November 2019 в 20:09
поделиться

Это довольно просто в использовании label, можно повредить внешний цикл от внутреннего цикла с помощью маркировки, Рассмотреть пример ниже,

public class Breaking{
    public static void main(String[] args) {
        outerscope:
        for (int i=0; i < 5; i++) {
            for (int j=0; j < 5; j++) {
                if (condition) {
                    break outerscope;
                }
            }
        }
    }
}

, Другой подход должен использовать повреждающуюся переменную/флаг для отслеживания необходимое повреждение. рассмотрите следующий пример.

public class Breaking{ 
    public static void main(String[] args) {
        boolean isBreaking = false;
        for (int i=0; i < 5; i++) {
            for (int j=0; j < 5; j++) {
                if (condition) {
                    isBreaking = true;
                    break;
                }
            }
            if(isBreaking){
                break;
            }
        }
    }
}

Однако я предпочитаю использовать первый подход.

0
ответ дан 22 November 2019 в 20:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: