Управление потоком Java: операторы break и continue

Введение Условные операторы и циклы - очень важный инструмент в программировании. Есть немного вещей, которые мы могли бы сделать с кодом, который может выполняться только построчно. Вот что означает «управление потоком» - руководство выполнением нашей программы вместо того, чтобы позволить ей выполняться построчно, независимо от каких-либо внутренних или внешних факторов. Каждый язык программирования поддерживает ту или иную форму управления потоком, если не явно через ifs, fors или аналогичные операторы - тогда он неявно дает нам инструменты для

Вступление

Условные операторы и циклы - очень важный инструмент в программировании. Есть немного вещей, которые мы могли бы сделать с кодом, который может выполняться только построчно.

Вот что означает «управление потоком» - руководство выполнением нашей программы вместо того, чтобы позволить ей выполняться построчно, независимо от каких-либо внутренних или внешних факторов. Каждый язык программирования поддерживает некоторую форму управления потоком, если не явно через if s и for s или аналогичные операторы - тогда он неявно дает нам инструменты для создания таких конструкций, то есть языки программирования низкого уровня обычно достигают этого эффекта с большим go-to командам.

Циклы были концепцией, которая использовалась задолго до того, как компьютерное программирование стало вообще чем-то, но первой, кто использовал программный цикл, была Ада Лавлейс, широко известная под своей девичьей фамилией - Байрон, при вычислении чисел Бернулли еще в 19 веке.

В Java есть несколько способов управления потоком кода:

перерыв

Оператор break является одним из «операторов перехода» Java, поскольку он передает выполнение кода другой части кода. Мы уже видели ключевое слово break используемое в операторе switch . Мы вернемся к этому здесь вместе с другими вариантами использования:

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

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

 // Finding at which index element a is in an array 
 int[] arr = {1,2,3,4,5,6}; 
 int foundAt = -1; 
 
 int a = 4; 
 
 for (int i = 0; i < arr.length; i++) { 
 System.out.println(arr[i]); 
 if (arr[i] == a) { 
 foundAt = i; 
 break; 
 } 
 } 
 if (foundAt != -1) 
 System.out.println(a + " was found at index " + foundAt); 
 else System.out.println(a + " wasn't found in the array"); 

Выход:

 1 
 2 
 3 
 4 
 4 was found at index 3 

Как мы видим, for выполнялся как обычно, пока не встретился с break , после чего Java прекратила выполнение цикла и продолжила выполнение с первой строки после цикла for .

Вот еще один пример:

 Scanner s = new Scanner(System.in); 
 
 while (true) { 
 System.out.println("Do you wish to exit the infinite loop? Y/N"); 
 if (s.hasNext()) { 
 String answer = s.next(); 
 if (answer.equals("Y") || answer.equals("y")) 
 break; 
 } 
 } 

Этот цикл будет продолжать спрашивать пользователя, хочет ли он выйти из цикла, пока он не ответит соответствующими символами, где мы выйдем из цикла с помощью break , или завершим программу с помощью Ctrl + C

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

Если мы хотим , чтобы найти первую позицию , в которой определенный элемент можно найти в матрице, и мы хотели break из петли , как только мы его (аналогично примеру с массивом выше) обнаружили, написав следующее Wouldn не работает:

 int[][] matrix = {{1,2,3},{4,5,6},{7,8,9}}; 
 
 int foundAtI = -1; 
 int foundAtJ = -1; 
 
 int a = 4; 
 
 for (int i = 0; i < matrix.length; i++) { 
 for (int j = 0; j < matrix[i].length; j++) { 
 System.out.print(matrix[i][j] + " "); 
 if (matrix[i][j] == a) { 
 foundAtI = i; 
 foundAtJ = j; 
 break; 
 } 
 } 
 System.out.println(); 
 } 
 
 System.out.println(); 
 if (foundAtI != -1) 
 System.out.println(a + " was found at indices [" + foundAtI + "," + foundAtJ + "]"); 
 else System.out.println(a + " wasn't found in the matrix"); 

Выход:

 1 2 3 
 4 
 7 8 9 
 4 was found at indices [1,0] 

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

Здесь в игру вступают помеченные утверждения , которые мы рассмотрим дальше.

Помеченные заявления

Отмеченные операторы могут использоваться вместе с break или continue для имитации go-to .

Метки могут быть применены к любому блоку кода между {} , for , for-each , while , do-while , if и switch , а также выражениями, присваиваниями, операторами return , блоками try и операторами throw Затем мы используем их с операторами break и continue

Ярлыки работают путем применения идентификатора к конструкции:

 Identifier : Construct 

Такой как:

 someLoop: for (int i = 0; i < 100; i++) {} 
 someLabel: { 
 int i = 10; 
 } 

Затем мы можем вызвать эти помеченные операторы через break или continue . Например, здесь мы обозначили наш внешний цикл просто outer . Чтобы выйти из двух или более вложенных циклов, мы break внешний цикл, вызывая метку:

 outer: for (int i = 0; i < matrix.length; i++) { 
 for (int j = 0; j < matrix[i].length; j++) { 
 System.out.print(matrix[i][j] + " "); 
 if (matrix[i][j] == a) { 
 foundAtI = i; 
 foundAtJ = j; 
 break outer; 
 } 
 } 
 System.out.println(); 
 } 

Использование этого помеченного цикла вместо цикла в приведенном выше примере дает правильный результат и поведение:

 1 2 3 
 4 
 4 was found at indices [1,0] 

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

Продолжать

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

Для в while цикла, «пропуск» остальные итерации средств , идущих прямо назад проверить состояние до следующей итерации, а для for цикла этого средства будет «ступенчатой» часть for цикла (ту часть , где мы обычно увеличить / уменьшить управляющую переменную), а затем проверить условие перед следующей итерацией.

continue обычно используется с оператором if -> мы continue если будет выполнено определенное условие. Мы используем это, if выполняем оставшуюся часть итерации, только если условие не выполняется, и пропускаем использование continue . Например

 // We want to print every number from 1 to 20, except those divisible by 3 
 for (int i = 1; i <= 20; i++) { 
 if (i % 3 == 0) 
 continue; 
 
 System.out.println(i); 
 } 

continue в нашем примере можно было бы легко избежать, используя слегка измененный if , в основном печатая число, если i % 3 != 0 истинно, иначе ничего не делая.

Общий совет относительно как break и (особенно) continue - пытаться использовать их в основном в начале итераций в качестве некоторой формы предварительных условий, которые мы проверяем. Использование continue где-нибудь в середине итерации - отличный способ вызвать ошибки, на выяснение которых у вас уйдет время.

Конечно, вы также можете использовать continue с помеченными операторами:

 start: for (int i = 0; i < 10; i++) { 
 System.out.println(); 
 for (int j = 0; j < 10; j++) { 
 if (j >= i) 
 continue start; 
 } 
 System.out.println("Since j will always be equal to or more than i, the 'start' loop will continue running indefinitely, and this piece of code will never run."); 
 } 

Заключение

Управление потоком в коде важно практически для каждого приложения. Заявления, которые изменяют поток кода, являются фундаментальными строительными блоками, и каждый начинающий разработчик должен полностью контролировать / осознавать, как они работают.

Используя break и continue , разработчики Java могут имитировать go-to и при необходимости выходить из определенных циклов.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus