JavaRush /Java Blog /Random EN /switch statement in java

switch statement in java

Published in the Random EN group
Imagine that you are standing at a fork, like a hero from a famous painting. If you go to the left, you will lose your horse; if you go to the right, you will gain knowledge. How to program such a situation? You probably already know that we make such a choice using the if-then and if-then-else constructs .
if (turn_left) {
    System.out.println(«Коня потеряешь»);
}
if (turn_right) {
    System.out.println(“Знания обретёшь”);
}
else
    System.out.println(“Так и будешь стоять?);
But what if there are not two such tracks, but 10? Is there a track "very right", "a little left", "a little more left" and so on, in the amount of 10 pieces? Imagine how your if-then-else code will grow in this case!
if (вариант1)
{}
else if (вариант2)
{}else if (вариантN).
So, you do not have one fork of conditions, but several, say, 10 (it is important here that the number of forks is limited). For such situations, there is a special selection operator - switch case java .
switch (ВыражениеДляВыбора) {
           case  (Значение1):
               Код1;
               break;
           case (Значение2):
               Код2;
               break;
...
           case (ЗначениеN):
               КодN;
               break;
           default:
               КодВыбораПоУмолчанию;
               break;
       }
The order of execution in the statement is as follows:
  • ExpressionForSelection is evaluated. Next, the switch statement compares the resulting expression with the next Value (in the order of enumeration).
  • If the SelectionExpression matches the Value, then the code after the colon is executed.
  • If the break construction is encountered , then control is transferred outside the switch command.
  • If there is no match between ExpressionForSelection and Values, then control is transferred to the DefaultSelectionCode.
Important Points
  • The type of ExpressionForSelection for a switch statement in Java must be one of the following:

    • byte , short , char , int .
    • Their wrappers are Byte , Short , Character , Integer .
    • String (since Java 7).
    • Enumeration ( Enum ).
  • the default block is optional, then if the ExpressionForSelection and Values ​​do not match, no action will be taken.
  • break is optional, if it is not present, the code will continue execution (ignoring further comparisons of values ​​in case blocks) until the first encountered breakor until the end of the switch statement.
  • if it is necessary to execute the same code for several choices, to avoid duplication, we indicate several corresponding values ​​in front of it in successive case blocks .

Let's move on to the practice of using the switch statement in Java

Don't worry, we're done with the theory, and after further examples it will become much clearer. So let's get started. Let's take an example from astronomy about the planets of the solar system. In accordance with the latest international provisions, we will exclude Pluto (for the properties of its orbit). Recall that our planets are located from the Sun in the following sequence: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune. Let's create a Java method that receives as input the serial number of the planet (relative to the distance from the Sun), and outputs the main composition of the atmosphere of this planet as a List <String> list. Let me remind you that some planets have a similar composition of the atmosphere. Thus, Venus and Mars contain mainly carbon dioxide, Jupiter and Saturn have it composed of hydrogen and helium, and Uranus and Neptune, in addition to the last pair of gases, also have methane. Our function:
public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add("No Atmosphere");
            break;
        case 2:
        case 4: result.add("Carbon dioxide");
            break;
        case 3: result.add("Carbon dioxide");
            result.add("Nitrogen");
            result.add("Oxygen");
            break;
        case 5:
        case 6: result.add("Hydrogen");
            result.add("Helium");
            break;
        case 7:
        case 8: result.add("Methane");
            result.add("Hydrogen");
            result.add("Helium");
            break;
        default:
            break;
    }
    return result;
}
Please note: we compared the same code to planets identical in composition of atmospheres. And we did it at the expense of consecutive case constructions . In total, if we want to get the composition of the atmosphere of our home planet with you, we call our method with parameter 3:
getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) вернет нам [Углекислый газ, Азот, Кислород].
Experiment with break What happens if we remove all the break statements ? Let's try in practice:
public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add("No Atmosphere");
        case 2:
        case 4: result.add("Carbon dioxide");
        case 3: result.add("Carbon dioxide");
            result.add("Nitrogen");
            result.add("Oxygen");
        case 5:
        case 6: result.add("Hydrogen");
            result.add("Helium");
        case 7:
        case 8: result.add("Methane");
            result.add("Hydrogen");
            result.add("Helium");
        default:
    }
    return result;
}
If we print out the result of the method System.out.println(getPlanetAtmosphere(3)), then our home planet will not be so habitable. Or fit? Judge for yourself: [Carbon dioxide, Nitrogen, Oxygen, Hydrogen, Helium, Methane, Hydrogen, Helium], Why did this happen? The program has executed all cases after the first match until the end of the switch block.

Over-optimization break

Note that we can improve the method by placing the break directives and choices differently
public static List<String> getPlanetAtmosphere(int seqNumberFromSun) {
    List<String> result = new ArrayList<>();
    switch (seqNumberFromSun) {
        case 1: result.add("No Atmosphere");
                break;
        case 3: result.add("Nitrogen");
                result.add("Oxygen");
        case 2:
        case 4: result.add("Carbon dioxide");
                break;
        case 7:
        case 8: result.add("Methane");
        case 5:
        case 6: result.add("Hydrogen");
                result.add("Helium");
    }
     return result;
}
Looks shorter, right? We reduced the total number of statements by playing around with case ordering and regrouping. Now each type of gas is added to the list in only one line of code. The listing of the last example method is shown only to demonstrate how it works, it is highly discouraged to write in this style. If the author (and even more so third-party programmers) of similar code has to maintain it, then it will be very difficult to restore the logic of forming selection blocks and executable code for the java switch statement.

Differences from if

With the superficial similarity of if and switch statements , do not forget that the choice of execution options, the switch multiple choice statement is based on a SPECIFIC VALUE, while in if. can be any boolean expression. Keep this fact in mind when designing your code. Let's take a closer look at the innovations for switch in different versions of Java.

Switch in Java 7

Prior to Java 7, the byte, short, char, and int primitives could be used as the value for a switch. There was also support for enums and wrappers for the primitive types listed above: Character, Byte, Short, and Integer. But often we need to find the value of java switch string! How it would look like in Java 6:
DayOfWeek day = DayOfWeek.fromValue("Thursday");

switch (day) {
  case MONDAY:
     System.out.println("Today is windy !");
     break;
  case THURSDAY:
     System.out.println("Today is sunny !");
     break;
  case WEDNESDAY:
     System.out.println("Today is rainy!");
     break;
  default:
     System.out.println("Oooops, something wrong !");
And enum:
public enum DayOfWeek {
  MONDAY("Monday"),
  THURSDAY("Thursday"),
  WEDNESDAY("Wednesday"),
  NOT_FOUND("Not found");

  private final String value;

  DayOfWeek(final String value) {
     this.value = value;
  }

  public static DayOfWeek fromValue(String value) {
     for (final DayOfWeek dayOfWeek : values()) {
        if (dayOfWeek.value.equalsIgnoreCase(value)) {
           return dayOfWeek;
        }
     }
     return NOT_FOUND;
  }
}
But since Java 7, it has been possible to use the String type as the value for a switch switch:
String day = "Thursday";

switch (day) {
  case "Monday":
     System.out.println("Today is windy !");
     break;
  case "Thursday":
     System.out.println("Today is sunny !");
     break;
  case "Wednesday":
     System.out.println("Today is rainy!");
     break;
  default:
     System.out.println("Oooops, something wrong !");
}
Despite the new features, the enum approach is more flexible and recommended: we can reuse this enum many times.

Switch in Java 12

In Java 12, Switch expressions have been improved for pattern matching. If we use Switch as in the example above, to set the value of some variable, we had to calculate the value and assign to the given variable, and then use break:
int count = 2;
int value;
switch (count) {
  case 1:
     value = 12;
     break;
  case 2:
     value = 32;
     break;
  case 3:
     value = 52;
     break;
  default:
     value = 0;
}
But thanks to the capabilities of Java 12, we can rewrite this expression as follows:
int value = switch (count) {
  case 1:
     break 12;
  case 2:
     break 32;
  case 3:
     break 52;
  default:
     break 0;
};
Let's go through the changes a bit:
  1. If earlier we set a variable to a value inside case blocks, since the switch statement itself could not return anything, now we have such an opportunity, and we return the value directly using switch.

  2. Previously, we couldn’t have anything to the right of break, but now we use it as a return statement to return a value to our switch. Colon labels mark the entry point to a statement block. That is, the execution of all the code below begins from that place, even when another label is encountered.

    As a result, there is a through transition from mark to mark, which is also called a fall-through.

Switch statement in Java - 2To complete such a pass, you must either completely go through all the elements, or use break or return. An innovation in java 12 gives us the ability to use the lambda operator, which in turn guarantees that only the code to the right of it will be executed. Without any "failure". How would the previous example look like in this case:
int count = 2;
int value = switch (count) {
  case 1 -> 12;
  case 2 -> 32;
  case 3 -> 52;
  default -> 0;
};
The code has become much simpler, hasn't it? And one more thing: the lambda operator can also serve as a typical analogue of a colon, after which there is a whole block with some operations:
int count = 2;
int value = switch (count) {
  case 1 -> {
     //some computational operations...
     break 12;
  }
  case 2 -> {
     //some computational operations...
     break 32;
  }
  case 3 -> {
     //some computational operations...
     break 52;
  }
  default -> {
     //some computational operations...
     break 0;
  }
};
Well, what if we have the same return value for some cases? It turns out that we actually have the same cases for some different values. How could this be shortened with the new features of Java 12:
int count = 2;
int value = switch (count) {
  case 1, 3, 5 -> 12;
  case 2, 4, 6 -> 52;
  default -> 0;
};

Switch in Java 13

Java 13 has changed the way a switch returns a value. If in java 12 we wrote the return value after break, which served us as a return for the switch block, now we will return the value using the word yield . We look:
int value = switch (count) {
  case 1:
     yield 12;
  case 2:
     yield 32;
  case 3:
     yield 52;
  default:
     yield 0;
};
At the same time, code written in java 12 using break to return will not compile (( Switch statement in Java - 3Break will be used, but in situations where we do not need to return anything. Switch statement in Java - 4

Total

  • Use the case statement when the number of branches is more than two, so as not to clutter up the code with if-structures.
  • Don't forget to end the logical block of each branch corresponding to a particular value (case block) with a call to break .
  • The switch statement, in addition to some primitive types, can also use the Enum and String types as an expression .
  • Remember the default block - use it to handle unplanned select values.
  • To optimize performance, move the code branches with the most frequent choices to the beginning of the switch block.
  • Don't get carried away with "optimizing" by removing the break at the end of the case selection block - such code is difficult to understand and, as a result, difficult to maintain as it evolves.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION