JavaRush /Java blogi /Random-UZ /Java-da almashtirish bayonoti

Java-da almashtirish bayonoti

Guruhda nashr etilgan
Tasavvur qiling-a, siz mashhur rasmdagi qahramon kabi vilka yonida turibsiz. Chapga borsang otingdan ayrilasan, o‘ngga borsang ilm olasan. Bunday vaziyatni qanday dasturlash kerak? Biz if-then va if-then-else konstruksiyalari yordamida bunday tanlovni amalga oshirishimizni allaqachon bilasiz .
if (turn_left) {
    System.out.println(«Коня потеряешь»);
}
if (turn_right) {
    System.out.println(“Знания обретёшь”);
}
else
    System.out.println(“Так и будешь стоять?);
Agar bunday treklar ikkita emas, balki 10 ta bo'lsa-chi? 10 dona miqdorida "o'ngga", "bir oz chapga", "bir oz ko'proq chapga" va shunga o'xshash yo'l bormi? Ushbu versiyada if-then-else kodingiz qanday o'sishini tasavvur qiling !
if (вариант1)
{}
else if (вариант2)
{}else if (вариантN).
Shunday qilib, sizda bitta vilka sharti yo'q, lekin bir nechta, aytaylik, 10 (bu erda muhim narsa - vilkalar soni cheklangan). Bunday holatlar uchun maxsus tanlash operatori mavjud - switch case java .
switch (ВыражениеДляВыбора) {
           case  (Значение1):
               Код1;
               break;
           case (Значение2):
               Код2;
               break;
...
           case (ЗначениеN):
               КодN;
               break;
           default:
               КодВыбораПоУмолчанию;
               break;
       }
Bayonotdagi ijro tartibi quyidagicha:
  • SelectionExpression baholanadi. Keyinchalik, switch iborasi hosil bo'lgan ifodani keyingi Qiymat bilan (ko'rsatilgan tartibda) solishtiradi.
  • Agar SelectExpression Qiymatga mos kelsa, u holda ikki nuqtadan keyingi kod bajariladi.
  • Agar tanaffus konstruktsiyasiga duch kelsangiz , boshqaruv switch buyrug'idan tashqariga o'tkaziladi.
  • Agar ExpressionForSelection va Values ​​o'rtasida moslik topilmasa, boshqaruv DefaultSelectionCode-ga o'tkaziladi.
Muhim nuqtalar
  • Java-da kalit tanlash bayonoti uchun SelectionExpression turi quyidagilardan biri bo'lishi kerak:

    • bayt , qisqa , char , int .
    • Ularning o'ramlari bayt , qisqa , belgi , butun sondir .
    • String (Java 7 dan beri).
    • Ro'yxatga olish ( Enum ).
  • Standart blok ixtiyoriy, keyin SelectionExpression va Values ​​mos kelmasa, hech qanday harakat bajarilmaydi.
  • tanaffus ixtiyoriy; agar u mavjud bo'lmasa, kod birinchi breakalmashtirish bayonotiga duch kelgunga qadar yoki oxirigacha ishlashni davom ettiradi (xo'jalik bloklaridagi qiymatlarni keyingi taqqoslashlarga e'tibor bermaslik).
  • Agar bir nechta tanlov variantlari uchun bir xil kodni bajarish kerak bo'lsa, takrorlanishning oldini olish uchun biz ketma-ket ish bloklarida bir nechta mos qiymatlarni ko'rsatamiz .

Keling, Java-da switch operatoridan foydalanish amaliyotiga o'tamiz

Xavotir olmang, biz nazariyani tugatdik va keyingi misollardan keyin hamma narsa aniqroq bo'ladi. Shunday qilib, keling, boshlaylik. Keling, astronomiyadan Quyosh tizimidagi sayyoralar haqidagi misolni ko'rib chiqaylik. So'nggi xalqaro qoidalarga muvofiq, biz Plutonni (uning orbitasining xususiyatlari tufayli) chiqarib tashlaymiz. Bizning sayyoralarimiz Quyoshdan quyidagi ketma-ketlikda joylashganligini eslaylik: Merkuriy, Venera, Yer, Mars, Yupiter, Saturn, Uran va Neptun. Keling, Java usulini yarataylik, u kirish sifatida sayyoraning seriya raqamini (Quyoshdan masofaga nisbatan) oladi va chiqish sifatida ushbu sayyora atmosferasining asosiy tarkibini List <String> shaklida hosil qiladi . Eslatib o'taman, ba'zi sayyoralar o'xshash atmosferaga ega. Shunday qilib, Venera va Mars asosan karbonat angidridni o'z ichiga oladi, Yupiter va Saturn vodorod va geliydan iborat, Uran va Neptun esa oxirgi gaz juftligiga qo'shimcha ravishda metanga ham ega. Bizning funktsiyamiz:
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;
}
Iltimos, diqqat qiling: biz bir xil kodni bir xil atmosfera tarkibiga ega sayyoralar bilan taqqosladik. Va biz buni ketma-ket hol konstruktsiyalaridan foydalangan holda qildik . Shunday qilib, agar biz uy sayyoramiz atmosferasi tarkibini olishni istasak, biz 3-parametr bilan usulimizni chaqiramiz:
getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) вернет нам [Углекислый газ, Азот, Кислород].
Break bilan tajriba Agar biz barcha break iboralarini olib tashlasak nima bo'ladi ? Keling, buni amalda sinab ko'raylik:
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;
}
Agar biz usulning natijasini chop qilsak System.out.println(getPlanetAtmosphere(3)), bizning uy sayyoramiz hayot uchun unchalik mos kelmaydi. Yoki mos keladimi? O'zingiz baho bering: [Karbonat angidrid, Azot, Kislorod, Vodorod, Geliy, Metan, Vodorod, Geliy], Nega bunday bo'ldi? Dastur barcha ishlarni birinchi o'yindan keyin va o'tish blokining oxirigacha bajardi.

Haddan tashqari optimallashtirish tanaffusi

E'tibor bering, biz usulni tanaffus direktivalari va tanlash variantlarini boshqa tartibga solish bilan yaxshilashimiz mumkin
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;
}
Qisqaroq ko'rinadi, shunday emasmi? Ish tartibi va qayta guruhlash orqali biz bayonotlarning umumiy sonini kamaytirdik. Endi gazning har bir turi faqat bitta kod satrida ro'yxatga qo'shiladi. Usulning oxirgi namunasi ro'yxati faqat ishni namoyish qilish uchun ko'rsatilgan, bunday uslubda yozish tavsiya etilmaydi . Agar shunga o'xshash kodning muallifi (va undan ham ko'proq uchinchi tomon dasturchilari) uni saqlab qolishlari kerak bo'lsa, java switch bayonoti uchun tanlov bloklari va bajariladigan kodni shakllantirish mantiqini tiklash juda qiyin bo'ladi.

If dan farqlar

If va switch iboralari tashqi ko'rinishida o'xshash bo'lsa-da , bir nechta tanlov operatori almashtirish ijro opsiyalarini tanlashda MAXSUS QIYMATga asoslanishini unutmang, if-da esa. har qanday mantiqiy ifoda bo'lishi mumkin. Kodni loyihalashda ushbu faktni hisobga oling. Keling, Java-ning turli versiyalarida switch uchun innovatsiyalarni batafsil ko'rib chiqaylik.

Java 7 da o'tish

Java 7 dan oldin kalit uchun qiymat sifatida bayt, qisqa, char va int ibtidoiylaridan foydalanish mumkin edi. Yuqorida sanab o'tilgan ibtidoiy turdagi raqamlar va o'ramlar ham qo'llab-quvvatlandi: Belgi, Bayt, Qisqa va Butun son. Lekin ko'pincha biz java switch satrining qiymatini topishimiz kerak! Java 6 da shunday ko'rinadi:
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 !");
Va 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;
  }
}
Ammo Java 7 dan boshlab, String turini kalit uchun qiymat sifatida ishlatish mumkin edi:
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 !");
}
Yangi xususiyatlarga qaramay, enumdan foydalanish yondashuvi yanada moslashuvchan va foydalanish uchun tavsiya etiladi: biz bu raqamni ko'p marta ishlatishimiz mumkin.

Java 12 da o'tish

Java 12 naqshni moslashtirish uchun Switch ifodalarini yaxshilagan. Agar yuqoridagi misoldagidek Switch-dan foydalansak, ba'zi o'zgaruvchining qiymatini belgilash uchun biz qiymatni hisoblashimiz va uni berilgan o'zgaruvchiga belgilashimiz kerak edi, keyin esa break dan foydalaning:
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;
}
Ammo Java 12 ning imkoniyatlari tufayli biz ushbu ifodani quyidagicha qayta yozishimiz mumkin:
int value = switch (count) {
  case 1:
     break 12;
  case 2:
     break 32;
  case 3:
     break 52;
  default:
     break 0;
};
Keling, o'zgarishlarni biroz ko'rib chiqaylik:
  1. Agar ilgari case bloklari ichida o'zgaruvchi qiymatni o'rnatgan bo'lsak, chunki switch bayonotining o'zi hech narsani qaytara olmagan bo'lsa, endi bizda shunday imkoniyat bor va biz to'g'ridan-to'g'ri switch yordamida qiymatni qaytaramiz.

  2. Ilgari bizda tanaffusning o'ng tomonida hech narsa bo'lishi mumkin emas edi, lekin endi biz uni switchning qiymatini qaytarish uchun qaytarish bayonoti sifatida ishlatamiz. Ikki nuqta belgilari bayonot blokiga kirish nuqtasini belgilaydi. Ya'ni, o'sha paytdan boshlab, boshqa yorliqga duch kelganda ham, quyida keltirilgan barcha kodlarning bajarilishi boshlanadi.

    Natijada belgidan belgiga oxirigacha o'tish sodir bo'ladi, bu ham fall -through deb ataladi.

Java-da switch bayonoti - 2Bunday o'tishni bajarish uchun siz barcha elementlardan to'liq o'tishingiz kerak yoki break yoki qaytishdan foydalaning. Java 12-dagi yangilik bizga lambda operatoridan foydalanish imkoniyatini beradi, bu esa o'z navbatida faqat uning o'ng tomonidagi kod bajarilishini ta'minlaydi. Hech qanday "muvaffaqiyatsiz". Bu holda oldingi misol qanday ko'rinishga ega bo'ladi:
int count = 2;
int value = switch (count) {
  case 1 -> 12;
  case 2 -> 32;
  case 3 -> 52;
  default -> 0;
};
Kod ancha soddalashdi, shunday emasmi? Va yana bir narsa: lambda operatori yo'g'on ichakning odatiy analogi sifatida ham xizmat qilishi mumkin, shundan so'ng ba'zi operatsiyalar bilan butun blok mavjud:
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;
  }
};
Xo'sh, agar ba'zi hollarda qaytarish qiymati bir xil bo'lsa-chi? Ma'lum bo'lishicha, bizda turli xil qiymatlar uchun bir xil holatlar mavjud. Buni Java 12 da yangi funksiyalar yordamida qanday qilib qisqartirish mumkin:
int count = 2;
int value = switch (count) {
  case 1, 3, 5 -> 12;
  case 2, 4, 6 -> 52;
  default -> 0;
};

Java 13 da o'tish

Java 13 da kalitning qiymatni qaytarish usuli o'zgardi. Agar java 12 da biz uzilishdan keyin qaytish qiymatini yozgan bo'lsak, bu biz uchun switch bloki uchun qaytish bo'lib xizmat qilgan bo'lsa, endi biz qiymatni yield so'zidan foydalanib qaytaramiz . Keling, qaraylik:
int value = switch (count) {
  case 1:
     yield 12;
  case 2:
     yield 32;
  case 3:
     yield 52;
  default:
     yield 0;
};
Shu bilan birga, qaytish uchun break yordamida java 12 da yozilgan kod kompilyatsiya qilinmaydi (( Java-da switch bayonoti - 3Break ishlatiladi, lekin biz hech narsani qaytarishimiz kerak bo'lmagan holatlarda.

Jami

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