CodeGym /Blog Java /Aleatoriu /Declarație de comutare Java
John Squirrels
Nivel
San Francisco

Declarație de comutare Java

Publicat în grup

Un pic de teorie despre Java Switch

Imaginează-ți că ești un cavaler oprit la o bifurcație a drumului. Dacă mergi la stânga, îți vei pierde calul. Dacă mergi corect, vei dobândi cunoștințe. Cum am reprezenta această situație în cod? Probabil știți deja că folosim constructe precum if-then și if-then-else pentru a lua aceste decizii.

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?");

Dar dacă drumul nu se împarte în două, ci în zece? Ai drumuri care sunt „complet la dreapta”, „puțin la stânga de asta”, „un pic mai la stânga” și așa mai departe, însumând 10 drumuri posibile? Imaginează-ți cum va crește codul tău „dacă-atunci-altfel ” în această versiune!

if (option1)
{…}
else if (option2)
{…}
…
else if (optionN) ...
Să presupunem că aveți o bifurcație cu 10 direcții (este important aici ca numărul de opțiuni să fie finit). Pentru astfel de situații, Java are instrucțiunea switch .

       switch (ExpressionForMakingAChoice) {
           case (Value1):
               Code1;
               break;
           case (Value2):
               Code2;
               break;
...
           case (ValueN):
               CodeN;
               break;
           default:
               CodeForDefaultChoice;
               break;
       }

Iată cum funcționează declarația:
  • ExpressionForMakingAChoice este evaluat. Apoi, instrucțiunea switch compară valoarea rezultată cu următoarea ValueX (în ordinea în care sunt listate).
  • Dacă ExpressionForMakingAChoice se potrivește cu ValueX, atunci este executat codul care urmează două puncte.
  • Dacă este întâlnită o instrucțiune break , atunci controlul este transferat în afara instrucțiunii switch.
  • Dacă ExpressionForMakingAChoice nu se potrivește cu niciun ValueX, atunci controlul trece la CodeForDefaultCase.
Puncte importante
  • În instrucțiunea switch, tipul de ExpressionForMakingAChoice trebuie să fie unul dintre următoarele:

    • octet , scurt , char , int .
    • Byte , Short , Character , Integer (învelișuri ale tipurilor de date primitive).
    • String .
    • Enum .
  • Blocul implicit este opțional. Dacă este absent și ExpressionForMakingAChoice nu se potrivește cu niciun ValueX, atunci nu va fi executată nicio acțiune.
  • Declarația break nu este necesară. Dacă este absent, codul va continua să fie executat (ignorând comparațiile ulterioare în instrucțiunile case) până la prima apariție a break-ului sau până la sfârșitul instrucțiunii switch .
  • Dacă același cod trebuie executat pentru mai multe opțiuni, putem elimina dublarea prin specificarea mai multor instrucțiuni case consecutive.

Să aruncăm o privire acum la modul în care este utilizată instrucțiunea switch în Java

Nu-ți face griji: am terminat cu teoria. După ce vedeți următoarele exemple, totul va deveni mult mai clar. Ei bine, să începem. Să ne uităm la un exemplu din astronomie care implică planetele sistemului nostru solar. În conformitate cu cele mai recente atitudini internaționale, l-am exclus pe Pluto (din cauza proprietăților orbitei sale). Ne amintim că planetele noastre sunt aranjate după distanța lor față de Soare, astfel: Mercur, Venus, Pământ, Marte, Jupiter, Saturn, Uranus și Neptun. Să scriem o metodă Java care ia numărul ordinal al unei planete (în raport cu distanța acesteia de la Soare) și returnează principalele componente ale atmosferei planetei ca List <String>. Vă veți aminti că unele planete au o compoziție atmosferică similară. Astfel, Venus și Marte conțin în principal dioxid de carbon; atmosfera lui Jupiter și Saturn este formată din hidrogen și heliu; iar Uranus și Neptun adaugă metan la ultima pereche de gaze. Iată funcția noastră:

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;
}
Rețineți că folosim același cod pentru planete cu compoziții atmosferice identice. Am făcut acest lucru folosind declarații de caz consecutive . Dacă vrem să obținem compoziția atmosferei planetei noastre natale, numim metoda noastră cu 3 drept argument:

getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) returns ["Carbon dioxide", "Nitrogen", "Oxygen"].
Experimentați cu break: Ce se întâmplă dacă eliminăm toate instrucțiunile break ? Hai sa incercam:

    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;
    }
Dacă tipărim rezultatul System.out.println(getPlanetAtmosphere(3)) , atunci descoperim că planeta noastră de origine nu este atât de trăibilă. Sau este? Judecați singuri: ["Dioxid de carbon", "Azot", "Oxigen", "Hidrogen", "Heliu", "Metan", "Hidrogen", "Heliu"] . De ce s-a întâmplat asta? Programul execută toate instrucțiunile case după prima potrivire până la sfârșitul blocului de comutare .

Optimizarea excesivă a declarațiilor break

Rețineți că putem îmbunătăți metoda prin aranjarea diferită a instrucțiunilor break și a cazurilor.

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;
}
Pare mai puțin cod, nu? Am redus numărul total de declarații jucându-ne cu ordinea declarațiilor de caz și regrupându-le. Acum fiecare tip de gaz este adăugat la listă într-o singură linie de cod. Codul dat în ultimul exemplu este doar pentru a arăta cum funcționează lucrurile. Nu recomandăm scrierea codului în acest fel. Dacă autorul unui astfel de cod Java (darămite alți programatori) trebuie să îl mențină, va fi foarte dificil să reconstruiască logica din spatele formării acelor blocuri case și codul executat în instrucțiunea switch .

Diferențele față de dacă

Având în vedere asemănările exterioare ale instrucțiunilor if și switch , nu uitați că instrucțiunea switch selectează unul dintre cazuri pe baza unei VALORI SPECIFICE, în timp ce instrucțiunea if poate avea orice expresie booleană. Țineți cont de acest lucru atunci când vă proiectați codul.

Concluzie

  • Utilizați instrucțiunea case pentru mai mult de două ramuri pentru a nu aglomera codul cu instrucțiuni if.
  • Nu uitați să completați blocul logic al ramurii pentru fiecare valoare specifică (instrucțiunea caz) inserând o instrucțiune break .
  • Expresia instrucțiunii switch poate fi o Enum sau String , precum și unele tipuri primitive.
  • Amintiți-vă blocul implicit . Utilizați-l pentru a gestiona valori neașteptate.
  • Pentru a optimiza performanța, mutați ramurile de cod corespunzătoare celor mai comune valori la începutul blocului de comutare .
  • Nu vă lăsați dus de „optimizare” ștergând instrucțiunile break de la sfârșitul instrucțiunilor case – un astfel de cod este greu de înțeles și, prin urmare, greu de întreținut.
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION