Labeled Break and Continue Statements in Java
In Java, we can label the loops and give them names. These named or labeled loops help in the case of nested loops when we want to break or continue a specific loop out of those multiple nested loops.
The labeled blocks in Java are logically similar to goto statements in C/C++.
A label is any valid identifier followed by a colon. For example, in the following code, we are creating two labeled statements:
outer_loop: for (int i = 0; i < array.length; i++) < inner_loop: for (int j = 0; j < array.length; j++) < //. >//. >
In the above example, we have two loops, and we have labeled them as outer_loop and inner_loop. This is helpful when we want to terminate the outer loop from a condition written in the inner loop.
2. Difference between Simple break and Labeled break
The simple break statement in Java terminates only the immediate loop in which it is specified. So even if we break from the inner loop, it will still continue to execute the current iteration of the outer loop.
We must use the labeled break statement to terminate a specific loop, as the outer_loop in the above example.
In the same way, we can use the labeled continue statements to jump to the next iteration of any specific loop in the hierarchy of nested loops.
3. Labeled Statement with Other Conditional Statements
It is worth mentioning that labeled break and continue statements can be used with other flow control statements such as if-else statements, while-loop etc.
The following program uses the labeled break statement with a while-loop. Whenever during the program execution, the labeled break statement is encountered, then the control immediately goes out of the enclosing labeled block.
hackit: while (Some condition) < if ( a specific condition ) break hackit; //label else //normal business logic goes here.. >
Similarly, we can use these statements with the classical if-else statements as well.
int i = 10; outer_if: if(i > 0) < inner_if: if( i>5) < //. break outer_if; >else < //. >>
In this simple Java tutorial, we discussed the following points:
- Java does not have a general goto statement like a few other programming languages.
- The simple break and continue alter the normal flow control of the program. We can specify the named labels. A label should be a valid java identifier with a colon.
- Labeled blocks can only be used with break and continue statements.
- Labeled break and continue statements must be called within their scope. We can not refer them outside the scope of the labeled block.
- The break statement immediately jumps to the end (and out) of the appropriate compound statement.
- The continue statement immediately jumps to the appropriate loop’s next iteration (if any).
Branching Statements
The break statement has two forms: labeled and unlabeled. You saw the unlabeled form in the previous discussion of the switch statement. You can also use an unlabeled break to terminate a for , while , or do-while loop, as shown in the following BreakDemo program:
class BreakDemo < public static void main(String[] args) < int[] arrayOfInts = < 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 >; int searchfor = 12; int i; boolean foundIt = false; for (i = 0; i < arrayOfInts.length; i++) < if (arrayOfInts[i] == searchfor) < foundIt = true; break; > > if (foundIt) < System.out.println("Found " + searchfor + " at index " + i); >else < System.out.println(searchfor + " not in the array"); >> >
This program searches for the number 12 in an array. The break statement, shown in boldface, terminates the for loop when that value is found. Control flow then transfers to the statement after the for loop. This program’s output is:
An unlabeled break statement terminates the innermost switch , for , while , or do-while statement, but a labeled break terminates an outer statement. The following program, BreakWithLabelDemo , is similar to the previous program, but uses nested for loops to search for a value in a two-dimensional array. When the value is found, a labeled break terminates the outer for loop (labeled «search»):
class BreakWithLabelDemo < public static void main(String[] args) < int[][] arrayOfInts = < < 32, 87, 3, 589 >, < 12, 1076, 2000, 8 >, < 622, 127, 77, 955 >>; int searchfor = 12; int i; int j = 0; boolean foundIt = false; search: for (i = 0; i < arrayOfInts.length; i++) < for (j = 0; j < arrayOfInts[i].length; j++) < if (arrayOfInts[i][j] == searchfor) < foundIt = true; break search; >> > if (foundIt) < System.out.println("Found " + searchfor + " at " + i + ", " + j); >else < System.out.println(searchfor + " not in the array"); >> >
This is the output of the program.
The break statement terminates the labeled statement; it does not transfer the flow of control to the label. Control flow is transferred to the statement immediately following the labeled (terminated) statement.
The continue Statement
The continue statement skips the current iteration of a for , while , or do-while loop. The unlabeled form skips to the end of the innermost loop’s body and evaluates the boolean expression that controls the loop. The following program, ContinueDemo , steps through a String , counting the occurrences of the letter «p». If the current character is not a p, the continue statement skips the rest of the loop and proceeds to the next character. If it is a «p», the program increments the letter count.
class ContinueDemo < public static void main(String[] args) < String searchMe = "peter piper picked a " + "peck of pickled peppers"; int max = searchMe.length(); int numPs = 0; for (int i = 0; i < max; i++) < // interested only in p's if (searchMe.charAt(i) != 'p') continue; // process p's numPs++; >System.out.println("Found " + numPs + " p's in the string."); > >
Here is the output of this program:
To see this effect more clearly, try removing the continue statement and recompiling. When you run the program again, the count will be wrong, saying that it found 35 p’s instead of 9.
A labeled continue statement skips the current iteration of an outer loop marked with the given label. The following example program, ContinueWithLabelDemo , uses nested loops to search for a substring within another string. Two nested loops are required: one to iterate over the substring and one to iterate over the string being searched. The following program, ContinueWithLabelDemo , uses the labeled form of continue to skip an iteration in the outer loop.
class ContinueWithLabelDemo < public static void main(String[] args) < String searchMe = "Look for a substring in me"; String substring = "sub"; boolean foundIt = false; int max = searchMe.length() - substring.length(); test: for (int i = 0; i > foundIt = true; break test; > System.out.println(foundIt ? "Found it" : "Didn't find it"); > >
Here is the output from this program.
The return Statement
The last of the branching statements is the return statement. The return statement exits from the current method, and control flow returns to where the method was invoked. The return statement has two forms: one that returns a value, and one that doesn’t. To return a value, simply put the value (or an expression that calculates the value) after the return keyword.
The data type of the returned value must match the type of the method’s declared return value. When a method is declared void , use the form of return that doesn’t return a value.
The Classes and Objects lesson will cover everything you need to know about writing methods.
Оператор break в Java
Сегодня мы рассмотрим такую возможность языка программирования Java, как оператор перехода break. Это первая статья на тему операторов перехода, так что если вам понравится, буду рад написать еще. Сразу хочу заметить, что эта статья рассчитана в первую очередь на начинающих разработчиков, и более продвинутые ученики могут не найти здесь чего-то нового для себя. Итак, поехали. В Java существует 2 способа изменить порядок выполнения инструкций программы: операторы перехода и механизм обработки исключений. К операторам перехода в java относят три оператора: break, continue и return. Сегодня же я предлагаю Вам рассмотреть подробнее оператор break . Механизм обработки исключений является столь обширной темой, что выходит за рамки данной статьи. Есть три способа применения оператора break в java. Первый и самый популярный способ — использование break для досрочного выхода из цикла, например:
public class SimpleExample < public static void main(String[] args) < findNumberInLoop(3); >public static void findNumberInLoop(int number) < for (int i = 0; i < 10; i++) < if (i == number) < break; >System.out.println(i); > System.out.println("cycle was finished"); > >
Это означает, что когда счетчик цикла i становится равным переданному параметру number , то есть числу 3, выполнение цикла прерывается досрочно. Если в программе есть несколько вложенных друг в друга циклов, то break выводит только из самого внутреннего цикла, например:
public class SimpleExample < public static void main(String[] args) < findNumberInLoop(3); >public static void findNumberInLoop(int number) < for(int i = 0; i < 5; i++) < for (int j =0; j < 10; j++) < if(j == number) < break; >System.out.print(j); > System.out.println(); > System.out.println("cycles was finished"); > >
012 012 012 012 012 cycles was finished
Как видно из примера, внутренний цикл каждый раз прерывается на числе 3 (параметр number ), а внешний цикл выполняется 5 раз, как было и задумано. В java можно использовать более одного оператора break внутри цикла, но этого делать не рекомендуется, так как очень сильно ухудшается читабельность и структура кода. Второй способ применения break заключается в использовании его для прерывания выполнения операторов в ветвях switch , например:
public class SimpleExample < public static void main(String[] args) < square(2); >public static void square(int number) < switch (number)< case 1: System.out.println(number*number); break; case 2: System.out.println(number*number); break; case 3: System.out.println(number*number); break; >System.out.println("after switch"); > >
Оператор break передал управление коду следующему за всем блоком switch . Если же не указать break в switch в данном примере:
public class SimpleExample < public static void main(String[] args) < square(2); >public static void square(int number) < switch (number)< case 1: System.out.println(number*number); case 2: System.out.println(number*number); case 3: System.out.println(number*number); >System.out.println("after switch"); > >
Это произошло потому, что после выполнения блока case 2 программа продолжила выполнять все следующие за ним блоки case, что и дало нам соответствующий вывод. Иногда такая особенность оператора switch может быть нам выгодна, например:
public class SimpleExample < public static void main(String[] args) < compare(2); compare(7); compare(12); >public static void compare(int number) < switch (number)< case 0: case 1: case 2: case 3: case 4: case 5: System.out.println("number is less than 5 or equal 5"); break; case 6: case 7: case 8: case 9: System.out.println("number is greater than 5"); break; default: System.out.println("number is less than 0 or greater than 9"); >System.out.println("after switch"); > >
after switch number is greater than 5 after switch number is less than 0 or greater than 9 after switch
При первом вызове метода, оператор switch передает управление оператору case 2 и далее до оператора break в case 5 . Второй вызов происходит по аналогии с первым, но начинается c case 7 . Третий вызов же не находит подходящего значения среди всех case’ов, поэтому выполняется оператор default . Третий способ заключается в использовании оператора break вместо оператора goto из языка C. Для этого мы будем использовать особую форму оператора break , называемую break с меткой. Эта форма выглядит как break метка; Метка — это как правило любое подходящее из пространства имен java имя, предваряющее блок кода. При этом после применения этом блоке кода break с меткой приведет к тому, что код продолжит выполняться с места после блока с соответствующей меткой, например:
public class SimpleExample < public static void main(String[] args) < howWeUseLabels(true); System.out.println(); howWeUseLabels(false); >public static void howWeUseLabels(boolean bool) < firstBlock:< secondBlock:< thirdBlock:< System.out.println("We will see it always"); if(bool) < break secondBlock; >System.out.println("We won't see it if bool == true"); > System.out.println("We won't see it if bool == true"); > System.out.println("We will see it always"); > > >
We will see it always We will see it always We will see it always We won't see it if bool == true We won't see it if bool == true We will see it always
После первого вызова метода, оператор break осуществляет передачу управления в конец блока secondBlock , выходя из secondBlock и thirdBlock , при этом выполняя еще один оператор println() , в конце firstBlock . После второго вызова на экран выводится все строки. Метки можно использовать также для обозначения циклов. При этом следует помнить, что переходить к метке можно только изнутри блока кода, обозначенного меткой, например такой код не скомпилируется:
public class SimpleExample < public static void main(String[] args) < label:< System.out.println("inside label"); >if(true) < break label; >System.out.println("This is error"); > >
Замечания насчет чистоты кода и оператора break : Существует общепризнанный совет использовать оператор break очень осторожно, так как применение break усложняет понимание цикла и заставляет программиста заглянуть внутрь цикла, чтобы разобраться в нюансах его работы. Есть эвристического правило, что использовать break можно увереннее в более коротких циклах и с большей осторожностью в длинных и имеющих глубокую вложенность, так как это увеличивает вероятность ошибки и усложняет чтение и понимание вашего кода другими программистами. Как я уже писал выше, использование большого количества break , разбросанных по всему коду, говорит о том, что программист не до конца понимает, почему он написал свой код именно так. Возможно, стоит рассмотреть рефакторинг такого цикла, путем разбиения на несколько более маленьких циклов. Старайтесь с осторожностью использовать break с меткой в качестве замены goto , так как это усложняет структуру кода. Вот и все, что я хотел сегодня рассказать об операторе break в java. Буду рад конструктивной критике, а также готов написать продолжение про операторы continue и return , если Вам это интересно.