JavaRush /จาวาบล็อก /Random-TH /สลับคำสั่งใน Java

สลับคำสั่งใน Java

เผยแพร่ในกลุ่ม
ลองนึกภาพว่าคุณกำลังยืนอยู่ตรงทางแยกเหมือนฮีโร่จากภาพวาดชื่อดัง ถ้าคุณไปทางซ้าย คุณจะสูญเสียม้าของคุณ ถ้าคุณไปทางขวา คุณจะได้เรียนรู้ จะตั้งโปรแกรมสถานการณ์เช่นนี้ได้อย่างไร? คุณน่าจะรู้อยู่แล้วว่าเราตัดสินใจเช่นนั้นโดยใช้ โครงสร้าง 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 สำหรับคำสั่งการเลือกสวิตช์ใน Java ต้องเป็นอย่างใดอย่างหนึ่งต่อไปนี้:

    • ไบต์ , สั้น , ถ่าน , int _
    • wrapper ของพวกเขาคือByte , Short , Character , Integer
    • สตริง (ตั้งแต่ Java 7)
    • การแจงนับ ( อีนัม ).
  • บล็อกเริ่มต้นเป็นทางเลือก ดังนั้นหาก SelectionExpression และ Values ​​ไม่ตรงกัน จะไม่มีการดำเนินการใด ๆ
  • แบ่งเป็นทางเลือก หากไม่มีอยู่โค้ดจะดำเนินการต่อไป (โดยไม่สนใจการเปรียบเทียบค่าเพิ่มเติมในบล็อกกรณี) จนกว่าbreakจะพบคำสั่งสวิตช์แรกหรือจนกว่าจะสิ้นสุด
  • หากจำเป็นต้องรันโค้ดเดียวกันสำหรับตัวเลือกการเลือกหลายตัว เพื่อหลีกเลี่ยงการทำซ้ำเราจะระบุค่าที่สอดคล้องกันหลายค่าที่ด้านหน้าใน บล็อก ตัวพิมพ์ ที่ต่อเนื่อง กัน

มาดูการฝึกใช้คำสั่ง switch ใน Java กันดีกว่า

ไม่ต้องกังวล เราจบทฤษฎีนี้แล้ว และหลังจากตัวอย่างเพิ่มเติม ทุกอย่างจะชัดเจนขึ้นมาก มาเริ่มกันเลย เรามาดูตัวอย่างจากดาราศาสตร์เกี่ยวกับดาวเคราะห์ในระบบสุริยะกัน ตามกฎระเบียบระหว่างประเทศล่าสุด เราจะไม่รวมดาวพลูโต (เนื่องจากคุณสมบัติของวงโคจรของมัน) ให้เราจำไว้ว่าดาวเคราะห์ของเราอยู่ห่างจากดวงอาทิตย์ตามลำดับต่อไปนี้: ดาวพุธ ดาวศุกร์ โลก ดาวอังคาร ดาวพฤหัสบดี ดาวเสาร์ ดาวยูเรนัส และดาวเนปจูน มาสร้างวิธีการ Java ที่ได้รับอินพุตหมายเลขซีเรียลของดาวเคราะห์ (สัมพันธ์กับระยะห่างจากดวงอาทิตย์) และเอาต์พุตจะสร้างองค์ประกอบหลักของบรรยากาศของดาวเคราะห์ดวงนี้ในรูปแบบของ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;
}
โปรดทราบ: เราเปรียบเทียบรหัสเดียวกันกับดาวเคราะห์ที่มีองค์ประกอบบรรยากาศเหมือนกัน และเราทำสิ่งนี้โดยใช้โครงสร้างเคส ที่ต่อเนื่องกัน ดังนั้นหากเราต้องการได้องค์ประกอบบรรยากาศของดาวเคราะห์บ้านเกิดของเรา เราก็เรียกวิธีการของเราว่าพารามิเตอร์ 3:
getPlanetAtmosphere(3).
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");
        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;
}
ดูสั้นลงใช่ไหมล่ะ? เราลดจำนวนคำสั่งทั้งหมดลงโดยการเล่นกับ ลำดับเคสและการจัดกลุ่มใหม่ ตอนนี้ก๊าซแต่ละประเภทจะถูกเพิ่มเข้าไปในรายการด้วยรหัสเพียงบรรทัดเดียวเท่านั้น รายการตัวอย่างสุดท้ายของวิธีนี้จะแสดงขึ้นเพื่อสาธิตการทำงานเท่านั้นไม่แนะนำอย่างยิ่งให้เขียนในลักษณะดังกล่าว หากผู้เขียน (และโปรแกรมเมอร์บุคคลที่สามมากกว่านั้น) ของโค้ดที่คล้ายกันต้องดูแลรักษามันไว้ การคืนค่าตรรกะสำหรับการสร้างบล็อกการเลือกและโค้ดที่ปฏิบัติการได้สำหรับคำสั่ง java switch จะเป็นเรื่องยากมาก

ความแตกต่างจากถ้า

แม้ว่าคำสั่ง ifและswitchจะมีลักษณะคล้ายกัน แต่อย่าลืมว่าสวิตช์ตัวดำเนินการแบบเลือกหลายตัวเลือกจะยึดตัวเลือกการดำเนินการตาม SPECIFIC VALUE ในขณะที่ if อาจเป็นนิพจน์เชิงตรรกะใดก็ได้ คำนึงถึงข้อเท็จจริงนี้เมื่อออกแบบโค้ดของคุณ มาดูนวัตกรรมต่างๆ ของสวิตช์ใน Java เวอร์ชันต่างๆ กันดีกว่า

สลับใน Java 7

ก่อนที่ Java 7 จะสามารถใช้ไบต์, short, char และ int primitives เป็นค่าสำหรับสวิตช์ได้ นอกจากนี้ยังมีการรองรับ enum และ wrapper ประเภทดั้งเดิมที่แสดงไว้ด้านบน: อักขระ ไบต์ แบบสั้น และจำนวนเต็ม แต่บ่อยครั้งเราจำเป็นต้องค้นหาค่าของสตริงสวิตช์ Java! นี่คือสิ่งที่จะดูเหมือนใน Java 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 !");
และแจงนับ:
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;
  }
}
แต่เริ่มต้นด้วย Java 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 นี้ซ้ำได้หลายครั้ง

สลับใน Java 12

Java 12 ได้ปรับปรุงนิพจน์สวิตช์สำหรับการจับคู่รูปแบบ หากเราใช้ Switch ดังตัวอย่างด้านบน เพื่อตั้งค่าของตัวแปรบางตัว เราต้องคำนวณค่าและกำหนดให้กับตัวแปรที่กำหนด จากนั้นจึงใช้ตัวแบ่ง:
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;
}
แต่ด้วยความสามารถของ Java 12 เราจึงสามารถเขียนนิพจน์นี้ใหม่ได้ดังนี้:
int value = switch (count) {
  case 1:
     break 12;
  case 2:
     break 32;
  case 3:
     break 52;
  default:
     break 0;
};
มาดูการเปลี่ยนแปลงกันสักหน่อย:
  1. หากก่อนหน้านี้เราตั้งค่าตัวแปรไว้ภายใน case block เนื่องจากคำสั่ง switch เองไม่สามารถส่งคืนสิ่งใดได้ ตอนนี้เรามีโอกาสดังกล่าว และเราส่งคืนค่าโดยตรงโดยใช้ switch

  2. ก่อนหน้านี้เราไม่สามารถมีสิ่งใดที่อยู่ทางขวาของตัวแบ่งอีกต่อไป แต่ตอนนี้เราใช้มันเป็นคำสั่ง return เพื่อส่งคืนค่าของสวิตช์ของเรา เครื่องหมายโคลอนทำเครื่องหมายจุดเริ่มต้นในบล็อกคำสั่ง นั่นคือจากจุดนั้น การดำเนินการของโค้ดทั้งหมดด้านล่างจะเริ่มต้นขึ้น แม้ว่าจะพบป้ายกำกับอื่นก็ตาม

    ผลลัพธ์ที่ได้คือการเปลี่ยนผ่านจากจุดหนึ่งไปอีกจุดหนึ่ง ซึ่งเรียกอีกอย่างว่าการล้มผ่าน

สลับคำสั่งใน Java - 2เพื่อให้ผ่านได้สำเร็จ คุณต้องผ่านองค์ประกอบทั้งหมดให้ครบถ้วน หรือใช้ตัวแบ่งหรือย้อนกลับ นวัตกรรมใน java 12 ช่วยให้เราใช้ตัวดำเนินการ lambda ได้ ซึ่งจะทำให้มั่นใจได้ว่ามีเพียงโค้ดทางด้านขวาเท่านั้นที่จะถูกดำเนินการ โดยไม่มี "ความล้มเหลว" ใดๆ ตัวอย่างก่อนหน้านี้จะมีลักษณะอย่างไรในกรณีนี้:
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;
  }
};
แล้วถ้าในบางกรณีค่าที่ส่งคืนจะเท่ากันล่ะ? ปรากฎว่าจริงๆ แล้วเรามีกรณีเดียวกันสำหรับค่าที่ต่างกันบางค่า นี่คือวิธีที่สามารถย่อให้สั้นลงได้โดยใช้คุณสมบัติใหม่ใน Java 12:
int count = 2;
int value = switch (count) {
  case 1, 3, 5 -> 12;
  case 2, 4, 6 -> 52;
  default -> 0;
};

สลับใน Java 13

ใน Java 13 วิธีที่สวิตช์ส่งคืนค่ามีการเปลี่ยนแปลง หากใน java 12 เราเขียนค่าที่ส่งคืนหลังตัวแบ่ง ซึ่งทำหน้าที่เป็นค่าส่งคืนสำหรับบล็อกสวิตช์ ตอนนี้เราจะคืนค่าโดยใช้คำว่าallowance มาดูกัน:
int value = switch (count) {
  case 1:
     yield 12;
  case 2:
     yield 32;
  case 3:
     yield 52;
  default:
     yield 0;
};
ในขณะเดียวกันโค้ดที่เขียนด้วย Java 12 โดยใช้ตัวแบ่งเพื่อส่งคืนจะไม่คอมไพล์ (( สลับคำสั่งใน Java - 3จะใช้ตัวแบ่ง แต่ในสถานการณ์ที่เราไม่จำเป็นต้องส่งคืนสิ่งใด ๆ

ทั้งหมด

  • ใช้ คำสั่ง caseเมื่อมีสาขามากกว่าสองสาขาเพื่อหลีกเลี่ยงไม่ให้โค้ดของคุณยุ่งเหยิงด้วยโครงสร้าง if
  • อย่าลืมจบบล็อกลอจิคัลของแต่ละสาขาที่สอดคล้องกับค่าเฉพาะ (บล็อกตัวพิมพ์) ด้วยการเรียกพัก
  • นอกจากประเภทพื้นฐานบางประเภทแล้ว คำสั่ง switch ยังสามารถใช้ ประเภท EnumและString เป็นนิพจน์ ได้ ด้วย
  • จำ บล็อก เริ่มต้น - ใช้เพื่อจัดการค่าการเลือกที่ไม่ได้วางแผนไว้
  • เพื่อเพิ่มประสิทธิภาพการทำงาน ให้ย้ายสาขาโค้ดที่มีตัวเลือกที่พบบ่อยที่สุดไปยังจุดเริ่มต้นของบล็อกสวิตช์
  • อย่าหลงไปกับ "การเพิ่มประสิทธิภาพ" ด้วยการลบตัวแบ่งที่ส่วนท้ายของ บล็อกการเลือก เคสออก - โค้ดดังกล่าวเข้าใจยาก และเป็นผลให้บำรุงรักษาได้ยากในระหว่างการพัฒนา
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION