Switch, na elegancko

AUTOR: MAREK SOWA

Często pisząc kod, natrafimy na szereg różnych warunków, które musimy uwzględnić. Gdy warunkami są przedziały danych, z pomocą przychodzi nam już znana instrukcja warunkowa if. Warto ją przypomnieć:

int age = 20;
if (age<16){
    System.out.println("Masz za mało lat");
} else if(age>=16 && age<18){
    System.out.println("Potrzebujesz zgody rodzica");
} else {
    System.out.println("Masz odpowiedni wiek");
}

 

Co natomiast w sytuacji, gdy rozpatrując warunek, mamy wiele wyborów do przeanalizowania? Z pomocą przychodzi instrukcja switch. W świecie programowania przyjęło się stwierdzenie, że instrukcja switch jest bardziej elegancka niż instrukcja warunkowa if. Oczywiście zwykły if jest w stanie poradzić sobie z każdą sytuacją warunkową, ponieważ konstrukcję else if teoretycznie możemy stosować w nieskończoność. Tak, jak w poniższym przykładzie:

if (degree<2){
    System.out.println("Jedynka! godzej być nie mogło..");
} else if(degree>=2 && degree<3){
    System.out.println("Dwója! fatalnie..");
} else if(degree>=3 && degree<4){
     System.out.println("Trója! nic z ciebie nie będzie..");
} else if(degree>=4 && degree<5){
    System.out.println("Czwóreczka! no, no..");
} else if(degree>=5 && degree<6){
    System.out.println("Piąteczka! brawo, brawo!");
} else if(degree>=6 && degree<7){
    System.out.println("Szósteczka! Niesamowite! Jesteś najlepszy!");
} else {
    System.out.println("coś, kręcisz.. Nie ma takich ocen");
}

Spójrzcie na zależność warunkową. Widzimy, że każda kolejna ocena (degree) różni się od poprzedniej tylko o jeden - nie jest to przedział, tylko konkretne wartości. W takiej sytuacji od razu powinniśmy myśleć o switch, który stworzony został do takich właśnie zadań:

switch (degree){
     case 1:{
         System.out.println("Jedynka! godzej być nie mogło..");
         break;
     } 
     case 2:{
         System.out.println("Dwója! fatalnie..");
         break;
     } 
     case 3:{
         System.out.println("Trója! nic z ciebie nie będzie..");
         break;
     } 
     case 4: {
         System.out.println("Czwóreczka! no, no..");
         break;
     } 
     case 5: {
         System.out.println("Piąteczka! brawo, brawo!");
         break;
     } 
     case 6: {
         System.out.println("Szósteczka! Niesamowite! Jesteś najlepszy!");
         break;
     } 
     default:
         System.out.println("coś, kręcisz.. Nie ma takich ocen");
         break;
 }

 

Słowo kluczowe case oznacza rozpatrzenie kolejnej potencjalnej decyzji po początkowym sprawdzeniu warunku.

*Nie zapominajmy przy case po wartości zmiennej wstawić znak dwukropka ':'

Switch czy else if

Switch używamy zawsze tam, gdzie się tylko da. Switch jest szybszy od else if, ponieważ warunek sprawdzany jest tylko raz. Późniejsze przełączanie się też jest zdecydowanie szybsze. W instrukcji else if, program musi po raz kolejny sprawdzić warunek w nawiasie. To może oznaczać wykonanie skomplikowanej metody, która z kolei może przetwarzać tysiące danych i w międzyczasie posiłkować się jeszcze innymi metodami. Dla skomplikowanych programów takie uchybienie powodowałoby marnowanie mocy obliczeniowej. Ponadto switch wygląda czytelniej, ładniej... Po prostu bardziej elegancko. =] 

 

Break

Zapewne zwróciliście uwagę, że każdy case jest zakończony break. Jest to słowo kluczowe i konieczne. Niestety większość IDE w standardzie nie wstawia automatycznie break, a początkujący programiści mają skłonność do zapominania o nim. Bez break program nie będzie wiedział, gdzie kończy się instrukcja w bloku case. Program będzie kontynuował, wykonując wykonywanie instrukcji dopóty, dopóki nie znajdzie słowa kluczowego break lub nie wykona wszystkich instrukcji w całym bloku switch:

int degree = 4;
switch (degree){
     case 1:{
         System.out.println("Jedynka! godzej być nie mogło..");
     }
     case 2:{
         System.out.println("Dwója! fatalnie..");
     }
     case 3:{
         System.out.println("Trója! nic z ciebie nie będzie..");
     }
     case 4: {
         System.out.println("Czwóreczka! no, no..");
     }
     case 5: {
         System.out.println("Piąteczka! brawo, brawo!");
     }
     case 6: {
         System.out.println("Szósteczka! Niesamowite! Jesteś najlepszy!");
     }
     default:
         System.out.println("coś, kręcisz.. Nie ma takich ocen");
 }
output//
Czwóreczka! no, no..
Piąteczka! brawo, brawo!
Szósteczka! Niesamowite! Jesteś najlepszy!
coś, kręcisz.. Nie ma takich ocen

 

Jak widzimy w outpucie program analizując kolejne case, przełączył się na case 4: i zaczął wykonywać instrukcję. Niestety programista zapomniał zakończyć tego case'a breakiem. Program wykonywał się dalej i dalej... i jak widać wypisał wynik dla 5, 6 oraz default. 

 

Default

Słowo kluczowe default działa prawie tak samo, jak słowo kluczowe else w instrukcji warunkowej if. Default również jest opcjonalny, więc można stworzyć switch bez default.
Default jest odpowiedzią na wszystkie inne warianty, czyli case, których nie przewidujemy, a jednak mogą wystąpić:

switch(name){
    case "Ania":
        System.out.println("Jesteś Anna");
        break;
    case "Agniesia": 
        System.out.println("Jesteś Agnieszka");
        break;
    case "Monia":
        System.out.println("Jesteś Monika");
        break;
    default:
        System.out.println("Nie znam cię");
        break;
}

 

Wygodnicki switch

Pisząc instrukcję switch, nie musimy pamiętać o kolejności case, jak w przypadku instrukcji if. W if jeżeli pierwszy warunek został spełniony, to wykonywała się instrukcja w jego bloku i program przechodził dalej. W switch warunek sprawdzany jest tylko raz na początku i przełączy się na właściwy casejeżeli taki będzie. Niezależnie w którym miejscu go umieścimy, czy na początku, końcu, czy gdzieś pośrodku:

switch (degree){
    case 5: {
        System.out.println("Piąteczka! brawo, brawo!");
        break;
    }
    case 2:{
        System.out.println("Dwója! fatalnie..");
        break; 
    }
    case 3:{
        System.out.println("Trója! nic z ciebie nie będzie..");
        break; 
    }
    default:
        System.out.println("coś, kręcisz.. Nie ma takich ocen");
        break;
    case 1:{
        System.out.println("Jedynka! godzej być nie mogło..");
        break;
    }
    case 6: {
        System.out.println("Szósteczka! Niesamowite! Jesteś najlepszy!");
        break;
    }
    case 4: {
         System.out.println("Czwóreczka! no, no..");
         break;
     }
 }

 

Warto jednak pisać kolejne case w jakimś porządku. Na przykład od najmniejszej wartości do największej bądź od 'a do z'. Zawsze starajmy się pisać czysty kod, tak zwany clean code, tak, by każdy programista mógł wejść w nasz kod i analizować go bez żadnych trudności.