การใช้สองค่าสำหรับคำสั่ง switch case หนึ่งคำสั่ง


295

ในรหัสของฉันโปรแกรมทำบางสิ่งบางอย่างขึ้นอยู่กับข้อความที่ป้อนโดยผู้ใช้ รหัสของฉันดูเหมือนว่า:

switch (name) {
        case text1: {
            //blah
            break;
        }
        case text2: {
            //blah
            break;
        }
        case text3: {
            //blah
            break;
        }
        case text4: {
            //blah
            break;
        }

อย่างไรก็ตามรหัสในกรณีtext1และtext4เหมือนกัน ฉันจึงสงสัยว่ามันจะเป็นไปได้ไหมที่ฉันจะทำอะไรบางอย่างที่เป็นไปได้

case text1||text4: {
            //blah
            break;
        }

ฉันรู้ว่า||ผู้ประกอบการจะไม่ทำงานในคำสั่งกรณี แต่มีสิ่งที่คล้ายกันฉันสามารถใช้


32
การเป็นคำถามพื้นฐานจะทำให้เกิดอะไรขึ้นถ้ามีคุณสมบัติเหมาะสมมากสำหรับ upvotes หากไม่ใช่ของซ้ำที่มีประโยชน์อย่างกว้างขวาง และบางสิ่งบางอย่างที่ไม่ได้เกิดขึ้นกับฉันเท่าที่จะทำได้ แต่ตอนนี้ฉันรู้แล้วว่ามันชัดเจนมาก ดังนั้นทั้งหมดในคำถามที่น่ากลัวสวย
Richard Tingle

1
@RichardTingle - คุณคุ้นเคยกับอุปกรณ์ของดัฟฟ์ - en.wikipedia.org/wiki/Duff%27s_device
user93353

4
"ทำไมต้องมีผู้อัปโหลดจำนวนมากค้นหา" java switch "ในอินเทอร์เน็ตและอ่านคำอธิบายหนึ่งพันรายการ" <- คุณคิดว่าฉันทำอะไรอยู่
เบรนแดน

4
ฉันค้นหาคำว่า "หลายกรณีในหนึ่งบรรทัด java" และคำถาม & คำตอบนี้เป็นผลลัพธ์แรก
domenix

1
การสาธิตสวิตช์ในคำตอบที่เลือกสามารถนำมาใช้ใหม่ได้ในขณะนี้ที่ JDK-12 ได้รวม JEP-325 :)
Naman

คำตอบ:


555

คุณสามารถใช้มีทั้งสองCASEคำสั่งดังนี้

  case text1: 
  case text4:{
            //blah
            break;
        }

ดูตัวอย่างนี้: ตัวอย่างโค้ดจะคำนวณจำนวนวันในแต่ละเดือน:

class SwitchDemo {
    public static void main(String[] args) {

        int month = 2;
        int year = 2000;
        int numDays = 0;

        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                numDays = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                numDays = 30;
                break;
            case 2:
                if (((year % 4 == 0) && 
                     !(year % 100 == 0))
                     || (year % 400 == 0))
                    numDays = 29;
                else
                    numDays = 28;
                break;
            default:
                System.out.println("Invalid month.");
                break;
        }
        System.out.println("Number of Days = "
                           + numDays);
    }
}

นี่คือผลลัพธ์จากรหัส:

Number of Days = 29

เจ๊ง:

อีกจุดที่น่าสนใจคือคำสั่ง break แต่ละคำสั่ง break จะยกเลิกคำสั่ง switch ที่ปิดล้อม การควบคุมการไหลดำเนินการต่อด้วยคำสั่งแรกหลังจากบล็อกสวิตช์ งบแบ่งเป็นสิ่งที่จำเป็นเพราะไม่มีงบงบในสวิตช์บล็อกfall through: งบทั้งหมดหลังจากที่ฉลากกรณีที่ตรงกันจะดำเนินการในลำดับโดยไม่คำนึงถึงการแสดงออกของป้ายชื่อกรณีที่ตามมาจนกว่าจะพบคำสั่งแบ่ง

รหัสตัวอย่าง:

public class SwitchFallThrough {

    public static void main(String[] args) {
        java.util.ArrayList<String> futureMonths =
            new java.util.ArrayList<String>();

        int month = 8;

        switch (month) {
            case 1:  futureMonths.add("January");
            case 2:  futureMonths.add("February");
            case 3:  futureMonths.add("March");
            case 4:  futureMonths.add("April");
            case 5:  futureMonths.add("May");
            case 6:  futureMonths.add("June");
            case 7:  futureMonths.add("July");
            case 8:  futureMonths.add("August");
            case 9:  futureMonths.add("September");
            case 10: futureMonths.add("October");
            case 11: futureMonths.add("November");
            case 12: futureMonths.add("December");
            default: break;
        }

        if (futureMonths.isEmpty()) {
            System.out.println("Invalid month number");
        } else {
            for (String monthName : futureMonths) {
               System.out.println(monthName);
            }
        }
    }
}

นี่คือผลลัพธ์จากรหัส:

August
September
October
November
December

การใช้สตริงในสวิทช์คำสั่ง

ใน Java SE 7 และใหม่กว่าคุณสามารถใช้วัตถุ String ในการแสดงออกของคำสั่งเปลี่ยน ตัวอย่างโค้ดต่อไปนี้แสดงจำนวนเดือนตามค่าของ String ที่ชื่อเดือน:

public class StringSwitchDemo {

    public static int getMonthNumber(String month) {

        int monthNumber = 0;

        if (month == null) {
            return monthNumber;
        }

        switch (month.toLowerCase()) {
            case "january":
                monthNumber = 1;
                break;
            case "february":
                monthNumber = 2;
                break;
            case "march":
                monthNumber = 3;
                break;
            case "april":
                monthNumber = 4;
                break;
            case "may":
                monthNumber = 5;
                break;
            case "june":
                monthNumber = 6;
                break;
            case "july":
                monthNumber = 7;
                break;
            case "august":
                monthNumber = 8;
                break;
            case "september":
                monthNumber = 9;
                break;
            case "october":
                monthNumber = 10;
                break;
            case "november":
                monthNumber = 11;
                break;
            case "december":
                monthNumber = 12;
                break;
            default: 
                monthNumber = 0;
                break;
        }

        return monthNumber;
    }

    public static void main(String[] args) {

        String month = "August";

        int returnedMonthNumber =
            StringSwitchDemo.getMonthNumber(month);

        if (returnedMonthNumber == 0) {
            System.out.println("Invalid month");
        } else {
            System.out.println(returnedMonthNumber);
        }
    }
}

ผลลัพธ์จากรหัสนี้คือ 8

จากเอกสาร Java


โอวตกลง. นั่นเป็นเรื่องง่าย ไม่ทราบว่าฉันสามารถทำได้
Ankush

18
เป็นมูลค่าการกล่าวถึงว่าคุณสมบัติภาษานี้เรียกว่าการฝ่าฝืน กรณีโดยไม่มีbreakจะถูกผนวกเข้ากับพื้นบล็อกกรณีต่อไปซึ่งเป็นสายตาด้านล่างจึงตกผ่าน
Emperor Orionii

5
@ Kobor42 ก่อนอื่นเรียนรู้วิธีการพูดคุยในเว็บไซต์สาธารณะคำแนะนำของคุณจะช่วยได้อย่างไรขอบคุณ
PSR

1
@ Kobor42 แล้ว: ทำไมคุณใช้การจัดรูปแบบนั้น การวางเคสน่ากลัวทำให้โค้ดอ่านน้อยลงและโดยทั่วไปถือว่าเป็นวิธีปฏิบัติที่ไม่ดี [ตัวเลือกอ้างอิง แต่ต้องการ] ฉันมักจะรู้สึกว่างบ switch เป็นรูปแบบที่อ่านได้โดยเฉพาะ แต่นำเสนอด้วยวิธีนี้พวกเขาสูญเสียทั้งหมดที่
Richard Tingle

2
การสาธิตสวิตช์สามารถนำมาใช้ใหม่ได้ในขณะนี้ที่ JDK-12 ได้รวม JEP-325 :)
Naman


27

caseค่าเป็นเพียง Codeless "โกโตะ" จุดที่สามารถใช้ร่วมกันจุดเริ่มต้นเหมือนกัน:

case text1:
case text4: 
    //blah
    break;

โปรดทราบว่าการจัดฟันซ้ำซ้อน


@trig lol ฉันกำลังทำสิ่งนั้นมากเมื่อเร็ว ๆ นี้ - กล่าวโทษการพิมพ์ด้วยนิ้วหัวแม่มือของ iPhone ไชโย
ชาวโบฮีเมีย


15

ด้วยการรวมJEP 325: Switch Expressions (Preview)ในการสร้างการเข้าถึงก่อนเวลา JDK-12 ตอนนี้หนึ่งสามารถใช้รูปแบบใหม่ของฉลากสวิตช์เป็น: -

case text1, text4 -> {
     //blah
} 

หรือเพื่อใช้ถ้อยคำสาธิตจากคำตอบอย่างใดอย่างหนึ่งดังนี้: -

public class RephraseDemo {

    public static void main(String[] args) {
        int month = 9;
        int year = 2018;
        int numDays = 0;

        switch (month) {
            case 1, 3, 5, 7, 8, 10, 12 ->{
                numDays = 31;
            }
            case 4, 6, 9, 11 ->{
                numDays = 30;
            }
            case 2 ->{
                if (((year % 4 == 0) &&
                        !(year % 100 == 0))
                        || (year % 400 == 0))
                    numDays = 29;
                else
                    numDays = 28;
            }
            default ->{
                System.out.println("Invalid month.");

            }
        }
        System.out.println("Number of Days = " + numDays);
    }
}

นี่คือวิธีที่คุณสามารถทดลองใช้ - รวบรวมตัวอย่างคุณสมบัติ JDK12 ด้วย Maven


6

วงเล็บไม่จำเป็น แค่ทำ

case text1:
case text4:
  doSomethingHere();
  break;
case text2:
  doSomethingElse()
  break;

หากมีใครอยากรู้อยากเห็นสิ่งนี้จะเรียกว่ากรณีผิดพลาด ความสามารถในการทำเช่นนี้คือเหตุผลว่าทำไมจึงbreak;จำเป็นต้องยุติคำสั่งกรณีและปัญหา สำหรับข้อมูลเพิ่มเติมโปรดดูบทความในวิกิพีเดียhttp://en.wikipedia.org/wiki/Switch_statement


5

fallthroughตอบโดยคนอื่นเป็นคนดี

อย่างไรก็ตามวิธีการอื่นจะแยกวิธีออกจากเนื้อหาของคำสั่งเคสของคุณและจากนั้นเรียกวิธีการที่เหมาะสมจากแต่ละกรณี

ในตัวอย่างด้านล่างทั้งสองกรณี 'text1' และกรณี 'text4' จะทำงานเหมือนกัน:

switch (name) {
        case text1: {
            method1();
            break;
        }
        case text2: {
            method2();
            break;
        }
        case text3: {
            method3();
            break;
        }
        case text4: {
            method1();
            break;
        }

โดยส่วนตัวแล้วฉันพบว่ารูปแบบการเขียนคำสั่งกรณีนี้สามารถคงไว้และอ่านได้มากกว่าโดยเฉพาะเมื่อวิธีการที่คุณโทรมีชื่อที่อธิบายได้ดี


1
มันจะไม่สามารถบำรุงรักษาได้มากขึ้นหากtext1และtext4เกือบจะทำสิ่งเดียวกันโดยไม่คำนึงถึงการเปลี่ยนแปลงในอนาคต หากพวกเขาควรได้รับการเชื่อมโยงทำให้การเปลี่ยนแปลงในกรณีที่text1(หมายถึงการเปลี่ยนแปลงวิธีการที่จะเรียก) text4จะต้องมีการเปลี่ยนแปลงใน ในกรณีนี้จะเห็นได้ชัดว่าไม่สามารถบำรุงรักษาได้มากขึ้น มันขึ้นอยู่กับสถานการณ์
Nick Freeman

1
ฉันจะบอกว่าวิธีนี้ควรจะรวมกับวิธีอื่น ๆ ต่อไปเนื่องจากงบ switch ไม่ใช่ (IMHO) โครงสร้างการเขียนโปรแกรมที่สวยที่สุด
Nick Freeman

5

การผ่านเข้าใกล้เป็นวิธีที่ดีที่สุดที่ฉันรู้สึก

case text1:
case text4: {
        //Yada yada
        break;
} 


4

ค่าเคสเป็นเพียงจุดที่ไม่มีรหัส "โกโตะ" ที่สามารถแชร์จุดเข้าใช้งานเดียวกันได้:

case text1:
case text4: {
// ทำบางอย่าง
ผิดพลาด;
}

โปรดทราบว่าการจัดฟันซ้ำซ้อน


1

JEP 354: Switch Expressions (ดูตัวอย่าง)ใน JDK-13 และ JEP 361: Switch Expressions (Standard)ใน JDK-14 จะขยายคำสั่ง switchเพื่อให้สามารถใช้เป็นนิพจน์ได้

ตอนนี้คุณสามารถ:

  • โดยตรงตัวแปรกำหนดจากการแสดงออกของสวิทช์ ,
  • ใช้สวิตช์รูปแบบใหม่ของฉลาก ( case L ->):

    รหัสทางด้านขวาของฉลากสวิตช์ "case L ->" ถูก จำกัด ให้เป็นนิพจน์บล็อกหรือ (เพื่อความสะดวก) คำสั่งส่งข้อความ

  • ใช้หลายค่าคงที่ต่อกรณีคั่นด้วยเครื่องหมายจุลภาค
  • และยังไม่มีการแบ่งค่าอีกต่อไป:

    เพื่อให้ได้ค่าจากการแสดงออกของสวิทช์, breakกับคำสั่งมูลค่าจะลดลงในความโปรดปรานของyieldคำสั่ง

ดังนั้นตัวอย่างจากหนึ่งในคำตอบอาจมีลักษณะเช่นนี้:

public class SwitchExpression {

  public static void main(String[] args) {
      int month = 9;
      int year = 2018;
      int numDays = switch (month) {
        case 1, 3, 5, 7, 8, 10, 12 -> 31;
        case 4, 6, 9, 11 -> 30;
        case 2 -> {
          if (java.time.Year.of(year).isLeap()) {
            System.out.println("Wow! It's leap year!");
            yield 29;
          } else {
            yield 28;
          }
        }
        default -> {
          System.out.println("Invalid month.");
          yield 0;
        }
      };
      System.out.println("Number of Days = " + numDays);
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.