Рубрики
Без рубрики

Выход из вложенных циклов

Исследуйте различные способы выхода из цикла в Java.

Автор оригинала: baeldung.

1. Обзор

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

2. Проблема

Вложенные циклы очень полезны, например, для поиска в списке списков.

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

Во-первых, мы бы прошлись по списку студентов. Затем, внутри этого цикла, мы прокручивали список запланированных курсов.

Когда мы напечатаем имена студентов и курсы, мы получим следующий результат:

student 0
  course 0
  course 1
student 1
  course 0
  course 1

Мы хотели найти первого студента, который запланировал курс 0 . Однако, если мы просто используем циклы, то приложение продолжит поиск после того, как курс будет найден.

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

3. Перерыв

Первый вариант, который мы должны выйти из вложенного цикла, – это просто использовать оператор break :

String result = "";
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            break;
        }
    }
}
return result;

У нас есть внешний цикл и внутренний цикл, оба цикла имеют две итерации. Если счетчик внутреннего цикла равен 0, мы выполняем команду break . Когда мы запустим пример, он покажет следующий результат:

outer0inner0outer1inner0

Или мы могли бы скорректировать код, чтобы сделать его немного более читабельным:

outer 0
  inner 0
outer 1
  inner 0

Это то, чего мы хотим?

Почти, внутренний цикл завершается оператором break после нахождения 0. Однако внешний цикл продолжается, чего мы не хотим. Мы хотим полностью прекратить обработку, как только получим ответ.

4. Помеченный перерыв

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

String result = "";
myBreakLabel:
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            break myBreakLabel;
        }
    }
}
return result;

A помеченный break завершит внешний цикл, а не только внутренний цикл. Мы достигаем этого, добавляя метку my Break вне цикла и изменяя оператор break на stop my Break Label . После выполнения примера мы получим следующий результат:

outer0inner0

Мы можем прочитать его немного лучше с некоторым форматированием:

outer 0
  inner 0

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

5. Возвращение

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

String result = "";
for (int outerCounter = 0; outerCounter < 2; outerCounter++) {
    result += "outer" + outerCounter;
    for (int innerCounter = 0; innerCounter < 2; innerCounter++) {
        result += "inner" + innerCounter;
        if (innerCounter == 0) {
            return result;
        }
    }
}
return "failed";

Метка удаляется, и оператор break заменяется оператором return .

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

6. Заключение

Итак, мы только что рассмотрели, что делать, когда нам нужно рано выйти из цикла, например, когда мы нашли предмет, который мы ищем. Ключевое слово break полезно для одиночных циклов, и мы можем использовать помеченные break s для вложенных циклов.

В качестве альтернативы мы можем использовать оператор return . Использование return делает код более читаемым и менее подверженным ошибкам, поскольку нам не нужно думать о разнице между немаркированными и помеченными разрывами.

Не стесняйтесь взглянуть на код на GitHub .