Управление потоком Java: оператор switch

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

Вступление

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

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

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

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

Заявление о переключении

Если мы хотим сравнить значение с несколькими значениями и выполнить код на основе их равенства, мы могли бы сделать что-то вроде:

 String input = "someCommand"; 
 
 if (input.equals("date")) { 
 System.out.println("The current date is: " + new Date()); 
 } else if (input.equals("help")) { 
 System.out.println("The possible commands are..."); 
 } else if (input.equals("list")) { 
 System.out.println("The files in this directory are..."); 
 } else if (input.equals("exit")) { 
 System.out.println("Exiting application..."); 
 } else { 
 System.out.println("Command Not Supported"); 
 } 

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

 switch(variable) { 
 case constant1: 
 // Do something if the variable is equal to constant1. 
 // constant1 must be of same type as variable 
 // or easily converted to, such as Integer -> int 
 break; 
 case constant2: 
 // Some code 
 break; 
 ... 
 default: 
 // Some code 
 break; 
 } 

Переменная, переданная в качестве switch является переменной или выражением, значение которого мы сравниваем. Это значение сравнивается с каждым из значений case Если проверяемая переменная соответствует любому из вариантов, выполняется код, следующий за этим регистром. Мы можем иметь столько case сколько захотим.

Здесь мы познакомились с четырьмя новыми ключевыми словами: switch , case , break и default .

выключатель

Оператор switch обычно принимает переменную, хотя он также может принимать выражение, если оно возвращает принятый тип:

 // Comparing the value 5 with case values 
 switch(5) { 
 // Cases 
 } 
 
 int x = 5; 
 int y = 10; 
 
 // Comparing the value 15 with case values 
 switch(x+y) { 
 // Cases 
 } 
 
 // Booleans are not supported by switch statements, 
 // so this won't compile 
 switch(!true) { 
 // Cases 
 } 

Если мы передадим switch null значение, возникнет NullPointerException

дело

Значение case должно быть константой времени компиляции . Это означает, что для всех case мы должны использовать литералы / константы (например, «abc», 5 и т. Д.) Или переменные, которые были объявлены final и которым присвоено значение:

 final int i = 5; 
 int y = 15; 
 final int z; 
 z = 25; 
 
 int x = 10; 
 switch(x) { 
 case i: 
 // i can't be changed at any point due to the 
 // `final` modifier, will compile 
 break; 
 case y: 
 // Won't compile as `y` isn't a compile-time constant 
 break; 
 case 10+10: 
 // Compiles, as 10+10 is a compile-time constant 
 break; 
 case z: 
 // Doesn't compile as z wasn't initialized with 
 // its declaration, thus it isn't considered to 
 // be a compile-time constant 
 break; 
 case null: 
 // Doesn't compile, there can't be a null case 
 break; 
 } 

Все случаи должны быть уникальными, иначе код Java не будет компилироваться. Если бы случаи не были уникальными, не было бы способа узнать, какой вариант выполнить среди повторяющихся значений.

перерыв

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

Например:

 int ourNumber = 1; 
 
 switch(ourNumber) { 
 case 1: 
 System.out.println("One"); 
 case 2: 
 System.out.println("Two"); 
 case 3: 
 System.out.println("Three"); 
 break; 
 case 4: 
 System.out.println("Four"); 
 } 

Вывод этого кода:

 One 
 Two 
 Three 

В этом примере поток выполнения "проваливается" от первого оператора case (который соответствует ourNumber ) до оператора break

Иногда это может приводить к выполнению нежелательных случаев, поэтому мы должны быть осторожны, добавляя break , и хорошая идея - добавлять их по умолчанию в каждом case и удалять их позже, если мы действительно хотим выполнить несколько вариантов для некоторых входных данных. Более подробную информацию об break можно найти здесь .

Если мы действительно хотим, чтобы один и тот же код выполнялся для нескольких случаев, используется обычный шаблон:

 ... 
 case "a": 
 case "b": 
 System.out.println("Variable is equal to constant1 or constant2!"); 
 break; 
 ... 

Это приведет к выполнению System.out.println если наша переменная равна либо "a" либо если она равна "b" .

По умолчанию

default - это фрагмент кода, который switch если переменная, которую мы ему передали, не соответствует ни одному из заданных случаев. Этот оператор является необязательным, но настоятельно рекомендуется во избежание ситуаций, когда пользовательский ввод прерывает весь поток приложения.

Принимаемые типы данных

variable переданная в качестве switch может быть одной из следующих:

  • символ
  • байт
  • короткая
  • int
  • Целое число
  • короткий
  • Байт
  • Персонаж
  • перечислить
  • Нить

Это огромный скачок по if и else-if , которые поддерживают только boolean выражения.

При этом мы можем легко переписать if / if-else из начала этой статьи:

 switch("someCommand") { 
 case "date": 
 System.out.println("The current date is: " + new Date()); 
 break; 
 case "help": 
 System.out.println("The possible commands are..."); 
 break; 
 case "list": 
 System.out.println("The files in this directory are..."); 
 break; 
 case "exit": 
 System.out.println("Exiting application..."); 
 break; 
 default: 
 System.out.println("Command Not Supported"); 
 break; 
 } 

Или, в качестве другого примера, мы могли бы передать целое число и заменить эту цепочку if и else-if более читаемым аналогом:

 int ourNumber = 4; 
 
 if (ourNumber == 1) { 
 System.out.println("One"); 
 } 
 else if (ourNumber == 2) { 
 System.out.println("Two"); 
 } 
 else if (ourNumber == 3) { 
 System.out.println("Three"); 
 } 
 else if (ourNumber == 4) { 
 System.out.println("Four"); 
 } 
 else { 
 System.out.println("Larger than 4"); 
 } 

Эквивалентный switch будет выглядеть следующим образом:

 switch(ourNumber) { 
 case 1: 
 System.out.println("One"); 
 break; 
 case 2: 
 System.out.println("Two"); 
 break; 
 case 3: 
 System.out.println("Three"); 
 break; 
 case 4: 
 System.out.println("Four"); 
 break; 
 default: 
 System.out.println("Larger than 4"); 
 break; 
 } 

Понятно, что если ourNumber равно 1, то код после case 1: будет выполнен, и на стандартный вывод будет выведено «One».

Примечание. В отличие от других типов данных, строки сравниваются не с == , а с .equals() при проверке всех случаев. Это сделано для того, чтобы сравнивать фактическое значение строк, а не расположение в памяти.

Вложенные операторы переключения

Мы можем вложить несколько операторов switch

 switch(var1) { 
 case constant1: 
 switch(var2) { 
 // ... 
 } 
 break; 
 case constant2: 
 ... 
 } 

Лямбда-выражения

В Java 12 есть новый, более лаконичный способ обработки switch с помощью лямбда-выражений.

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

 switch(ourNumber) { 
 case 7, 3, 8, 4 -> System.out.println("Very popular lucky number"); 
 case 5, 13, 9, 6 -> System.out.println("Kind of popular lucky number"); 
 default -> System.out.println("Not all that popular"); 
 } 
 
 // Or something like: 
 String s = switch(ourNumber) { 
 case 7, 3, 8, 4 -> "Very popular lucky number"; 
 // ... 
 } 
 System.out.println(s); 

Заключение

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

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