CodeGym/Blog Java/Poland/Instrukcja Switch w Java
Autor
Milan Vucic
Programming Tutor at Codementor.io

Instrukcja Switch w Java

Opublikowano w grupie Poland

Trochę teorii na temat Switch w Javie

Wyobraź sobie, że jesteś rycerzem, który zatrzymał się na rozwidleniu dróg. Jeśli pójdziesz w lewo, stracisz konia. Jeśli pójdziesz w prawo, zyskasz wiedzę. Jak przedstawilibyśmy tę sytuację w kodzie? Prawdopodobnie wiesz już, jak używać konstrukcji if-then i if-then-else do podejmowania decyzji.
if (turn_left) {
    System.out.println("You will lose your horse");
}
if (turn_right) {
    System.out.println("You will gain knowledge");
}
else
    System.out.println("So you're just going to stand there?");
Ale co jeśli droga rozdziela się nie na dwie, ale na dziesięć? Masz do wyboru drogi "całkowicie w prawo", "nieco w lewo od tej", "trochę bardziej w lewo" i tak dalej, w sumie 10 możliwych dróg. Wyobraź sobie, jak twój kod if-then-else urośnie w tym scenariuszu!
if (option1)
{}
else if (option2)
{}else if (optionN) ...
Załóżmy, że masz 10-kierunkowe rozwidlenie drogi (ważne jest, aby liczba opcji była skończona). Do takich sytuacji Java ma instrukcję switch.
switch (ExpressionForMakingAChoice) {
           case (Value1):
               Code1;
               break;
           case (Value2):
               Code2;
               break;
...
           case (ValueN):
               CodeN;
               break;
           default:
               CodeForDefaultChoice;
               break;
       }
Oto jak działa ta instrukcja:
  • Oceniana jest wartość ExpressionForMakingAChoice. Następnie instrukcja switch porównuje otrzymaną wartość z kolejnymi wartościami ValueX (w kolejności, w jakiej są wymienione).
  • Jeśli wartości ExpressionForMakingAChoice i ValueX są zgodne, wykonywany jest kod po dwukropku.
  • W przypadku napotkania instrukcji break, sterowanie jest przekazywane poza instrukcję switch.
  • Jeżeli wartości ExpressionForMakingAChoice i ValueX nie są zgodne, sterowanie przechodzi do sekcji domyślnej, CodeForDefaultCase.
Ważne punkty:
  • W instrukcji Switch oceniana wartość ExpressionForMakingAChoice musi należeć do jednego z poniższych typów:

    • byte, short, char, int.
    • Byte, Short, Character, Integer (typy osłonowe, wrappery typów prostych).
    • String.
    • Enum.
  • Blok domyślny (default) jest opcjonalny. Jeżeli go nie ma i wartość ExpressionForMakingAChoice nie jest zgodna z żadną z wartości ValueX, żadna akcja nie zostanie wykonana.

  • Wyrażenie break nie jest wymagane. Jeżeli go nie ma, kod będzie wykonywany (ignorując dalsze porównania w instrukcjach case) do pierwszego wystąpienia break lub do końca instrukcji switch.

  • Jeżeli ten sam kod ma być wykonany dla kilku opcji, możemy wyeliminować duplikację, umieszczając bezpośrednio po sobie kilka instrukcji case.

Przyjrzyjmy się, jak instrukcja switch jest używana w Javie

Nie martw się: skończyliśmy z teorią. Gdy zobaczysz poniższe przykłady, wszystko się wyjaśni. Okej, zaczynajmy. Spójrzmy na przykład z astronomii z planetami naszego układu słonecznego. Zgodnie z najnowszymi ustaleniami wykluczyliśmy Plutona (ze względu na właściwości jego orbity). Przypomnijmy, że układając planety według kolejności od Słońca otrzymamy następującą listę: Merkury, Wenus, Ziemia, Mars, Jowisz, Saturn, Uran i Neptun. Napiszmy metodę Java, która pobiera liczbę porządkową planety (według odległości od słońca) i zwraca główne składniki jej atmosfery jako List<String>. Pamiętaj, że niektóre planety mają podobny skład atmosfery. Zatem atmosfera Wenus i Marsa składa się głównie z dwutlenku węgla, atmosfera Jowisza i Saturna z wodoru i helu, a Uran i Neptun dodają metan do ostatniej pary gazów. Oto nasza funkcja:
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;
}
Zauważ, że używamy tego samego kodu dla planet o identycznym składzie atmosfery. Zrobiliśmy to za pomocą kolejnych instrukcji case. Jeżeli chcemy uzyskać skład atmosfery naszej macierzystej planety, wywołujemy naszą metodę z argumentem 3:
getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) returns ["Carbon dioxide", "Nitrogen", "Oxygen"].
Eksperyment z break: Co się stanie, jeśli usuniemy wszystkie instrukcje break? Spróbujmy:
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;
}
Jeżeli wyświetlimy wynik dla System.out.println(getPlanetAtmosphere(3)), okaże się, że nasza planeta nie nadaje się do życia. A może jednak? Oceń samodzielnie:
["Dwutlenek węgla", "Azot", "Tlen", "Wodór", "Hel", "Metan", "Wodór", "Hel"].
Dlaczego tak się stało? Program wykonuje wszystkie instrukcje case po pierwszym dopasowaniu, aż do końca bloku switch.

Nadmierna optymalizacja instrukcji break

Zwróć uwagę, że możemy ulepszyć tę metodę zmieniając rozmieszczenie instrukcji break i case.
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;
}
Wygląda na mniej kodu, prawda? Zmniejszyliśmy całkowitą liczbę instrukcji manipulując kolejnością instrukcji case i przegrupowując je. Teraz każdy rodzaj gazu pojawia się tylko w jednym wierszu kodu. Kod z tego przykładu służy jedynie do pokazania jak to wszystko działa. Nie zalecamy pisania kodu w ten sposób. Gdyby autor takiego kodu Java (nie wspominając o innych programistach) musiał utrzymywać go w przyszłości, będzie mu bardzo trudno zrekonstruować logikę rozmieszczenia bloków case i kodu wykonywanego w instrukcji switch.

Różnice względem instrukcji IF

Pamiętając o ogólnym podobieństwie instrukcji if i switch, nie zapominaj, że instrukcja switch wybiera jeden z przypadków (case) porównując KONKRETNĄ WARTOŚĆ, podczas gdy instrukcja if może zawierać dowolne wyrażenie logiczne. Pamiętaj o tym podczas projektowania kodu. Instrukcja Switch w Java - 1

Wnioski

  • Używaj instrukcji case przy więcej niż dwóch rozgałęzieniach, aby nie zaśmiecać kodu instrukcjami if.

  • Nie zapominaj o zamknięciu bloku logicznego rozgałęzienia dla każdej wartości (instrukcja case) przez wstawienie instrukcji break.

  • Wyrażenie instrukcji switch może być typu Enum lub String, a także niektórymi z typów prostych.

  • Pamiętaj o bloku default. Używaj go do obsługi nieoczekiwanych wartości.

  • Aby zoptymalizować wydajność, gałęzie odpowiadające najczęściej występującym wartościom umieść na początku bloku switch.

  • Nie daj się ponieść podczas "optymalizacji" usuwając instrukcje break na końcu bloków case – taki kod jest trudny do zrozumienia, a co za tym idzie, trudny w utrzymaniu.

Komentarze
  • Popularne
  • Najnowsze
  • Najstarsze
Musisz się zalogować, aby dodać komentarz
Ta strona nie ma jeszcze żadnych komentarzy