Вопрос: Вывод из вложенных циклов в 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.

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

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


1525


источник


Ответы:


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

Вы можете использовать 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

2057



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

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

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

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

366



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

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

186



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

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

112



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

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

76



возможно, с функцией?

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

31



You can use a temporary variable:

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

Depending on your function, you can also exit/return from the inner loop:

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

15



If you don't like breaks and gotos, you can use a "traditional" for loop instead the for-in, with an extra abort condition:

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

10



I needed to do a similar thing, but I chose not to use the enhanced for loop to do it.

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

9