JavaRush /Java Blogu /Random-AZ /Java-da keçid bəyanatı

Java-da keçid bəyanatı

Qrupda dərc edilmişdir
Təsəvvür edin ki, məşhur bir tablonun qəhrəmanı kimi çəngəldə dayanırsınız. Sola getsən atını itirərsən, sağa getsən elm qazanarsan. Belə bir vəziyyəti necə proqramlaşdırmaq olar? Çox güman ki, artıq bilirsiniz ki, biz if-thenif-then-else konstruksiyalarından istifadə edərək belə bir seçim edirik .
if (turn_left) {
    System.out.println(«Коня потеряешь»);
}
if (turn_right) {
    System.out.println(“Знания обретёшь”);
}
else
    System.out.println(“Так и будешь стоять?);
Bəs iki belə trek yox, 10 olarsa? 10 ədəd həcmində “sağa”, “bir az sola”, “bir az daha sola” və sairə yol varmı? Təsəvvür edin ki , if-then-else kodunuz bu versiyada necə böyüyəcək!
if (вариант1)
{}
else if (вариант2)
{}else if (вариантN).
Beləliklə, bir şərtiniz yoxdur, ancaq bir neçə, məsələn, 10 (burada vacib olan çəngəllərin sayının məhdud olmasıdır). Belə vəziyyətlər üçün xüsusi bir seçim operatoru var - switch case java .
switch (ВыражениеДляВыбора) {
           case  (Значение1):
               Код1;
               break;
           case (Значение2):
               Код2;
               break;
...
           case (ЗначениеN):
               КодN;
               break;
           default:
               КодВыбораПоУмолчанию;
               break;
       }
Bəyanatda icra qaydası belədir:
  • SelectionExpression qiymətləndirilir. Sonra, keçid ifadəsi nəticədə ortaya çıxan ifadəni növbəti Dəyərlə (sadalanan ardıcıllıqla) müqayisə edir.
  • Əgər SelectExpression Dəyərlə uyğun gəlirsə, onda iki nöqtədən sonrakı kod yerinə yetirilir.
  • Əgər fasilə konstruksiyasına rast gəlinərsə , idarəetmə keçid əmrindən kənara ötürülür.
  • ExpressionForSelection və Dəyərlər arasında heç bir uyğunluq tapılmadıqda, idarəetmə DefaultSelectionCode-a köçürülür.
Vacib məqamlar
  • Java-da keçid seçimi bəyanatı üçün SelectionExpression növü aşağıdakılardan biri olmalıdır:

    • bayt , qısa , char , int .
    • Onların sarğıları Bayt , Qısa , Xarakter , Tam ədəddir .
    • String (Java 7-dən bəri).
    • Sadalama ( Enum ).
  • Defolt blok isteğe bağlıdır, əgər SelectionExpression və Dəyərlər uyğun gəlmirsə, heç bir hərəkət yerinə yetirilməyəcək.
  • fasilə isteğe bağlıdır; əgər mövcud deyilsə, kod ilk breakkeçid ifadəsinə rast gələnə qədər və ya sona qədər icra etməyə davam edəcək (hal bloklarında dəyərlərin əlavə müqayisələrinə məhəl qoymadan).
  • bir neçə seçim variantı üçün eyni kodu yerinə yetirmək lazımdırsa, təkrarlamanın qarşısını almaq üçün onun qarşısında ardıcıl bloklarında bir neçə uyğun dəyəri göstəririk .

Java-da switch ifadəsindən istifadə praktikasına keçək

Narahat olmayın, biz nəzəriyyəni bitirdik və əlavə nümunələrdən sonra hər şey daha aydın olacaq. Beləliklə, başlayaq. Günəş sisteminin planetləri haqqında astronomiyadan bir nümunəyə baxaq. Ən son beynəlxalq qaydalara uyğun olaraq, biz Plutonu (orbitinin xüsusiyyətlərinə görə) istisna edəcəyik. Planetlərimizin Günəşdən aşağıdakı ardıcıllıqla yerləşdiyini xatırlayaq: Merkuri, Venera, Yer, Mars, Yupiter, Saturn, Uran və Neptun. Gəlin Java metodu yaradaq ki, giriş kimi planetin seriya nömrəsini (Günəşdən olan məsafəyə nisbətdə) qəbul edir və çıxış kimi bu planetin atmosferinin əsas tərkibini Siyahı <String> şəklində verir . Nəzərinizə çatdırım ki, bəzi planetlərin atmosfer tərkibi oxşardır. Belə ki, Venera və Marsda əsasən karbon qazı, Yupiter və Saturn hidrogen və heliumdan ibarətdir, Uran və Neptunda isə sonuncu qaz cütlüyündən əlavə metan da var. Bizim funksiyamız:
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;
}
Diqqət edin: biz eyni kodu eyni atmosfer tərkibinə malik planetlərlə müqayisə etdik. Biz bunu ardıcıl hal konstruksiyalarından istifadə etməklə etdik . Beləliklə, öz planetimizin atmosferinin tərkibini əldə etmək istəyiriksə, 3-cü parametrlə metodumuzu çağırırıq:
getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) вернет нам [Углекислый газ, Азот, Кислород].
Break ilə sınaq Bütün fasilə ifadələrini silsək nə olar ? Bunu praktikada sınayaq:
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;
}
Metodun nəticəsini çap etsək System.out.println(getPlanetAtmosphere(3)), bizim ana planetimiz həyat üçün o qədər də uyğun olmayacaq. Yoxsa uyğun? Özünüz mühakimə edin: [Karbon dioksid, Azot, Oksigen, Hidrogen, Helium, Metan, Hidrogen, Helium], Niyə belə oldu? Proqram bütün işləri ilk matçdan sonra və keçid blokunun sonuna qədər icra etdi.

Həddindən artıq optimallaşdırma fasiləsi

Qeyd edək ki, fasilə direktivlərinin və seçim seçimlərinin fərqli təşkili ilə metodu təkmilləşdirə bilərik
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;
}
Daha qısa görünür, elə deyilmi? Dava sırası ilə oynayaraq və yenidən qruplaşdıraraq ifadələrin ümumi sayını azaltdıq. İndi hər bir qaz növü yalnız bir kod sətirində siyahıya əlavə olunur. Metodun son nümunəsinin siyahısı yalnız işi nümayiş etdirmək üçün göstərilir, belə bir üslubda yazmaq tövsiyə edilmir . Oxşar kodun müəllifi (və daha çox üçüncü tərəf proqramçıları) onu saxlamalı olsa, seçim bloklarının və java keçid bəyanatı üçün icra olunan kodun formalaşması üçün məntiqi bərpa etmək çox çətin olacaq.

If-dən fərqlər

ifswitch ifadələri görünüşcə oxşar olsa da , unutma ki, çox seçimli operator keçid icra variantlarının seçimini SPESİFİK DƏYƏR üzərində qurur, if-də isə. istənilən məntiqi ifadə ola bilər. Kodunuzu tərtib edərkən bu faktı nəzərə alın. Java-nın müxtəlif versiyalarında keçid üçün yeniliklərə daha yaxından nəzər salaq.

Java 7-də keçid

Java 7-dən əvvəl keçid üçün dəyər kimi bayt, qısa, char və int primitivləri istifadə edilə bilərdi. Yuxarıda sadalanan ibtidai tiplərin enum və sarmalayıcıları üçün də dəstək var idi: Character, Byte, Short və Integer. Ancaq tez-tez java keçid sətirinin dəyərini tapmalıyıq! Java 6-da belə görünəcək:
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 !");
Və sadalayın:
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;
  }
}
Lakin Java 7-dən başlayaraq, keçid üçün bir dəyər kimi String növündən istifadə etmək mümkün oldu:
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 !");
}
Yeni xüsusiyyətlərə baxmayaraq, enum istifadə edən yanaşma daha çevikdir və istifadə üçün tövsiyə olunur: biz bu nömrəni dəfələrlə təkrar istifadə edə bilərik.

Java 12-də keçid

Java 12 nümunə uyğunluğu üçün keçid ifadələrini təkmilləşdirmişdir. Əgər yuxarıdakı misaldakı kimi Switch-dən istifadə etsək, hansısa dəyişənin qiymətini təyin etmək üçün dəyəri hesablayıb verilən dəyişənə təyin etməli, sonra isə break-dən istifadə etməli idik:
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;
}
Lakin Java 12-nin imkanları sayəsində biz bu ifadəni aşağıdakı kimi yenidən yaza bilərik:
int value = switch (count) {
  case 1:
     break 12;
  case 2:
     break 32;
  case 3:
     break 52;
  default:
     break 0;
};
Dəyişiklikləri bir az nəzərdən keçirək:
  1. Əgər əvvəllər biz case blokları daxilində dəyişən qiymət qoyduqsa, switch ifadəsinin özü heç nə qaytara bilmədiyi üçün indi bizim belə bir fürsətimiz var və biz birbaşa keçiddən istifadə edərək dəyəri qaytarırıq.

  2. Əvvəllər, biz artıq fasilə sağında heç nəyə malik deyildik, lakin indi biz onu keçidimizin dəyərini qaytarmaq üçün qaytarma ifadəsi kimi istifadə edirik. İki nöqtə işarələri bəyanat blokuna giriş nöqtəsini qeyd edir. Yəni, o andan etibarən, hətta başqa bir etiketlə qarşılaşdıqda belə, aşağıdakı bütün kodların icrası başlayır.

    Nəticə nişandan nişana keçiddir ki, bu da fall -through adlanır.

Java-da keçid ifadəsi - 2Belə bir keçidi tamamlamaq üçün ya bütün elementləri tam şəkildə keçməli, ya da break və ya geri dönmə üsullarından istifadə etməlisiniz. Java 12-dəki yenilik bizə lambda operatorundan istifadə etmək imkanı verir ki, bu da öz növbəsində yalnız onun sağındakı kodun yerinə yetirilməsini təmin edir. Heç bir "uğursuzluq" olmadan. Əvvəlki nümunə bu halda necə görünəcək:
int count = 2;
int value = switch (count) {
  case 1 -> 12;
  case 2 -> 32;
  case 3 -> 52;
  default -> 0;
};
Kod çox sadələşdi, elə deyilmi? Və daha bir şey: lambda operatoru kolonun tipik analoqu kimi də xidmət edə bilər, bundan sonra bəzi əməliyyatları olan bütöv bir blok var:
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;
  }
};
Yaxşı, əgər bəzi hallarda qaytarılma dəyəri eyni olarsa? Belə çıxır ki, bizdə əslində bəzi fərqli dəyərlər üçün eyni hallar var. Java 12-də yeni funksiyalardan istifadə etməklə bunu necə qısaltmaq olar:
int count = 2;
int value = switch (count) {
  case 1, 3, 5 -> 12;
  case 2, 4, 6 -> 52;
  default -> 0;
};

Java 13-də keçid

Java 13-də keçidin dəyəri qaytarma üsulu dəyişdi. Əgər java 12-də keçid bloku üçün bizim üçün qayıdış rolunu oynayan fasilədən sonra qaytarılan dəyəri yazdıqsa, indi yield sözündən istifadə edərək dəyəri qaytaracağıq . Baxaq:
int value = switch (count) {
  case 1:
     yield 12;
  case 2:
     yield 32;
  case 3:
     yield 52;
  default:
     yield 0;
};
Eyni zamanda, qayıtmaq üçün fasilədən istifadə edərək java 12-də yazılmış kod kompilyasiya edilməyəcək (( Java-da keçid ifadəsi - 3Break istifadə ediləcək, lakin heç bir şeyi qaytarmağımız lazım olmayan vəziyyətlərdə.

Ümumi

  • Используйте оператор case при числе ветвлений более двух, чтобы не загромождать if-структурами code.
  • Не забывайте завершать логический блок каждой ветки соответствующего конкретному значению (блок case) вызовом break.
  • Оператор switch помимо некоторых примитивных типов, в качестве выражения может использовать также типы Enum и String.
  • Помните про блок default – употребляйте его для обработки незапланированных значений выбора.
  • Для оптимизации производительности переместите ветки codeа с наиболее часто встречающимися вариантами выбора к началу блока switch.
  • Не увлекайтесь «оптимизацией» за счёт удаления break в конце блока выбора case – такой code сложен для понимания, и, How следствие, тяжело сопровождать при его развитии.
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION