JavaRush /وبلاگ جاوا /Random-FA /دستور سوئیچ در جاوا

دستور سوئیچ در جاوا

در گروه منتشر شد
تصور کنید که در کنار یک چنگال ایستاده اید، مانند یک قهرمان از یک نقاشی معروف. اگر به سمت چپ بروی، اسبت را گم می‌کنی، اگر به سمت راست بروی، علم به دست می‌آوری. چگونه چنین موقعیتی را برنامه ریزی کنیم؟ به احتمال زیاد از قبل می دانید که ما چنین انتخابی را با استفاده از ساختارهای if-then و if-then-else انجام می دهیم .
if (turn_left) {
    System.out.println(«Коня потеряешь»);
}
if (turn_right) {
    System.out.println(“Знания обретёшь”);
}
else
    System.out.println(“Так и будешь стоять?);
اگر دو آهنگ از این قبیل وجود نداشته باشد، بلکه 10 قطعه وجود داشته باشد، چه؟ آیا مسیر «به سمت راست»، «کمی به سمت چپ»، «کمی بیشتر به سمت چپ» و غیره به تعداد 10 قطعه وجود دارد؟ تصور کنید که چگونه کد if-then-else شما در این نسخه رشد خواهد کرد!
if (вариант1)
{}
else if (вариант2)
{}else if (вариантN).
بنابراین، شما یک چنگال شرایط ندارید، بلکه چندین، مثلاً 10 (نکته مهم در اینجا این است که تعداد چنگال ها محدود است). برای چنین شرایطی، یک اپراتور انتخاب ویژه وجود دارد - switch case java .
switch (ВыражениеДляВыбора) {
           case  (Значение1):
               Код1;
               break;
           case (Значение2):
               Код2;
               break;
...
           case (ЗначениеN):
               КодN;
               break;
           default:
               КодВыбораПоУмолчанию;
               break;
       }
دستور اجرا در بیانیه به شرح زیر است:
  • SelectionExpression ارزیابی می شود. بعد، دستور switch عبارت حاصل را با مقدار بعدی (به ترتیب فهرست شده) مقایسه می کند.
  • اگر SelectExpression با مقدار مطابقت داشته باشد، کد زیر دو نقطه اجرا می شود.
  • اگر با ساختار شکست مواجه شد ، کنترل به خارج از دستور سوئیچ منتقل می شود.
  • اگر هیچ منطبقی بین ExpressionForSelection و Values ​​یافت نشد، کنترل به DefaultSelectionCode منتقل می‌شود.
نکات مهم
  • نوع SelectionExpression برای دستور انتخاب سوئیچ در جاوا باید یکی از موارد زیر باشد:

    • بایت , کوتاه , char , int .
    • بسته بندی آنها عبارتند از Byte , Short , Character , Integer .
    • رشته (از جاوا 7).
    • شمارش ( Enum ).
  • بلوک پیش فرض اختیاری است، سپس اگر SelectionExpression و Values ​​مطابقت نداشته باشند، هیچ اقدامی انجام نخواهد شد.
  • break اختیاری است؛ اگر کد موجود نباشد، اجرای کد (با نادیده گرفتن مقایسه‌های بیشتر مقادیر در بلوک‌های case) تا زمانی که اولین breakدستور سوئیچ مواجه می‌شود یا تا پایان اجرا ادامه می‌یابد.
  • اگر لازم است یک کد برای چندین گزینه انتخاب اجرا شود، برای جلوگیری از تکراری، چندین مقدار متناظر را در مقابل آن در بلوک های حروف کوچک نشان می دهیم .

بیایید به تمرین استفاده از دستور switch در جاوا برویم

نگران نباشید، ما با تئوری تمام شده ایم و پس از مثال های بعدی همه چیز بسیار واضح تر خواهد شد. پس بیایید شروع کنیم. بیایید به مثالی از نجوم در مورد سیارات منظومه شمسی نگاه کنیم. طبق آخرین مقررات بین المللی، پلوتو را (به دلیل ویژگی های مدار آن) حذف خواهیم کرد. به یاد داشته باشیم که سیارات ما از خورشید به ترتیب زیر قرار دارند: عطارد، زهره، زمین، مریخ، مشتری، زحل، اورانوس و نپتون. بیایید یک متد جاوا بسازیم که به عنوان ورودی شماره سریال سیاره (نسبت به فاصله از خورشید) را دریافت می کند و به عنوان خروجی ترکیب اصلی جو این سیاره را به صورت List <String> می دهد . اجازه دهید یادآوری کنم که برخی از سیارات ترکیب جوی مشابهی دارند. بنابراین، زهره و مریخ عمدتاً حاوی دی اکسید کربن هستند، مشتری و زحل از هیدروژن و هلیوم و اورانوس و نپتون، علاوه بر آخرین جفت گاز، متان نیز دارند. عملکرد ما:
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;
}
لطفاً توجه داشته باشید: ما همان کد را با سیاراتی با ترکیبات جوی یکسان مقایسه کردیم. و ما این کار را با استفاده از ساختارهای case متوالی انجام دادیم . بنابراین، اگر بخواهیم ترکیب جو سیاره خود را بدست آوریم، روش خود را با پارامتر 3 فراخوانی می کنیم:
getPlanetAtmosphere(3).
System.out.println(getPlanetAtmosphere(3)) вернет нам [Углекислый газ, Азот, Кислород].
آزمایش با break اگر همه دستورات break را حذف کنیم چه اتفاقی می افتد ؟ بیایید آن را در عمل امتحان کنیم:
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;
}
اگر نتیجه روش را چاپ کنیم System.out.println(getPlanetAtmosphere(3))، سیاره ما برای زندگی چندان مناسب نخواهد بود. یا مناسب؟ خودتان قضاوت کنید: [دی اکسید کربن، نیتروژن، اکسیژن، هیدروژن، هلیم، متان، هیدروژن، هلیم]، چرا این اتفاق افتاد؟ این برنامه همه موارد را پس از اولین مسابقه و تا پایان بلوک سوئیچ اجرا کرد.

شکست بیش از حد بهینه سازی

توجه داشته باشید که ما می‌توانیم روش را با ترتیب متفاوتی از دستورالعمل‌های شکست و گزینه‌های انتخاب بهبود دهیم
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;
}
کوتاه تر به نظر می رسد، اینطور نیست؟ با بازی با نظم پرونده و گروه بندی مجدد، تعداد کل اظهارات را کاهش دادیم. اکنون هر نوع گاز تنها در یک خط کد به لیست اضافه می شود. فهرست آخرین نمونه روش فقط برای نشان دادن کار نشان داده شده است؛ نوشتن به چنین سبکی به شدت توصیه نمی شود . اگر نویسنده (و حتی بیشتر برنامه نویسان شخص ثالث) کدهای مشابه مجبور به حفظ آن باشند، بازیابی منطق تشکیل بلوک های انتخاب و کد اجرایی برای دستور سوئیچ جاوا بسیار دشوار خواهد بود.

تفاوت با if

در حالی که دستورهای if و switch از نظر ظاهری مشابه هستند ، فراموش نکنید که سوئیچ اپراتور چند گزینه ای انتخاب گزینه های اجرا را بر اساس یک مقدار مشخص است، در حالی که در if. می تواند هر عبارت منطقی باشد. این واقعیت را هنگام طراحی کد خود در نظر بگیرید. بیایید نگاهی دقیق تر به نوآوری های سوئیچ در نسخه های مختلف جاوا بیندازیم.

جاوا 7 را تغییر دهید

قبل از جاوا 7، بایت، short، char و int اولیه می‌توانست به عنوان مقدار سوئیچ استفاده شود. همچنین از enum و wrapperهای انواع ابتدایی ذکر شده در بالا پشتیبانی می شود: Character، Byte، Short و Integer. اما اغلب ما نیاز داریم که مقدار یک رشته سوئیچ جاوا را پیدا کنیم! این چیزی است که در جاوا 6 به نظر می رسد:
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 !");
و 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;
  }
}
اما با شروع جاوا 7، می‌توان از نوع String به عنوان مقدار سوئیچ استفاده کرد:
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 !");
}
با وجود ویژگی‌های جدید، رویکرد استفاده از enum انعطاف‌پذیرتر است و برای استفاده توصیه می‌شود: می‌توانیم بارها از این enum استفاده مجدد کنیم.

جاوا 12 را تغییر دهید

جاوا 12 عبارات سوئیچ را برای تطبیق الگو بهبود بخشیده است. اگر مانند مثال بالا از Switch استفاده کنیم، برای تنظیم مقدار یک متغیر، باید مقدار را محاسبه کرده و به متغیر داده شده اختصاص دهیم و سپس از break استفاده کنیم:
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;
}
اما به لطف قابلیت های جاوا 12، می توانیم این عبارت را به صورت زیر بازنویسی کنیم:
int value = switch (count) {
  case 1:
     break 12;
  case 2:
     break 32;
  case 3:
     break 52;
  default:
     break 0;
};
بیایید کمی تغییرات را مرور کنیم:
  1. اگر قبلاً یک مقدار متغیر را در داخل بلوک‌های case تنظیم می‌کردیم، از آنجایی که خود دستور switch نمی‌توانست چیزی را برگرداند، اکنون چنین فرصتی داریم و مستقیماً با استفاده از switch مقدار را برمی‌گردانیم.

  2. قبلاً دیگر نمی‌توانستیم چیزی در سمت راست break داشته باشیم، اما اکنون از آن به عنوان یک دستور بازگشت برای برگرداندن مقدار سوئیچ خود استفاده می‌کنیم. علامت های دو نقطه نقطه ورود به یک بلوک عبارت را مشخص می کنند. یعنی از آن نقطه اجرای تمام کدهای زیر شروع می شود، حتی زمانی که با برچسب دیگری مواجه می شوید.

    نتیجه یک انتقال پایان به انتها از علامت به علامت است که به آن سقوط از طریق نیز می گویند.

دستور سوئیچ در جاوا - 2برای تکمیل چنین پاسی یا باید تمام عناصر را به طور کامل طی کنید یا از break یا return استفاده کنید. نوآوری در جاوا 12 به ما امکان استفاده از عملگر لامبدا را می دهد که به نوبه خود تضمین می کند که فقط کد سمت راست آن اجرا می شود. بدون هیچ "شکست". مثال قبلی در این مورد چگونه خواهد بود:
int count = 2;
int value = switch (count) {
  case 1 -> 12;
  case 2 -> 32;
  case 3 -> 52;
  default -> 0;
};
کد بسیار ساده تر شده است، اینطور نیست؟ و یک چیز دیگر: عملگر لامبدا همچنین می تواند به عنوان یک آنالوگ معمولی یک کولون عمل کند، پس از آن یک بلوک کامل با برخی عملیات وجود دارد:
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;
  }
};
خوب، اگر برای برخی موارد مقدار بازگشتی یکسان باشد چه؟ معلوم می شود که ما در واقع موارد مشابهی برای مقادیر مختلف داریم. در اینجا نحوه کوتاه کردن آن با استفاده از ویژگی های جدید در جاوا 12 آمده است:
int count = 2;
int value = switch (count) {
  case 1, 3, 5 -> 12;
  case 2, 4, 6 -> 52;
  default -> 0;
};

جاوا 13 را تغییر دهید

در جاوا 13، روشی که سوئیچ یک مقدار را برمی گرداند تغییر کرده است. اگر در جاوا 12 مقدار بازگشتی را پس از استراحت نوشتیم که به عنوان بازگشتی برای بلوک سوئیچ برای ما عمل می کرد، اکنون مقدار را با استفاده از کلمه yield برمی گردانیم . بیایید نگاه بیندازیم:
int value = switch (count) {
  case 1:
     yield 12;
  case 2:
     yield 32;
  case 3:
     yield 52;
  default:
     yield 0;
};
در عین حال، کدی که در جاوا 12 با استفاده از break to return نوشته شده است، کامپایل نخواهد شد (( دستور سوئیچ در جاوا - 3Break استفاده خواهد شد، اما در شرایطی که نیازی به برگرداندن چیزی نداریم.

جمع

  • وقتی بیش از دو شاخه وجود دارد از دستور case استفاده کنید تا از بهم ریختگی کد خود با ساختارهای if جلوگیری کنید.
  • فراموش نکنید که بلوک منطقی هر شاخه مربوط به یک مقدار خاص (بلوک موردی) را با یک فراخوانی break پایان دهید .
  • علاوه بر برخی از انواع اولیه، دستور switch می تواند از انواع Enum و String نیز به عنوان عبارات استفاده کند .
  • بلوک پیش فرض را به خاطر بسپارید - از آن برای مدیریت مقادیر انتخاب برنامه ریزی نشده استفاده کنید.
  • برای بهینه سازی عملکرد، شاخه های کد با رایج ترین انتخاب ها را به ابتدای بلوک سوئیچ منتقل کنید.
  • با حذف شکاف در انتهای بلوک انتخاب مورد ، دچار "بهینه سازی" نشوید - درک چنین کدی دشوار است و در نتیجه حفظ آن در طول توسعه آن دشوار است.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION