Menggunakan dua nilai untuk satu pernyataan kasus sakelar

296

Dalam kode saya, program melakukan sesuatu tergantung pada teks yang dimasukkan oleh pengguna. Kode saya terlihat seperti:

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

Namun, kode di dalam case text1dan text4sama. Karena itu saya bertanya-tanya apakah mungkin bagi saya untuk mengimplementasikan sesuatu seperti

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

Saya tahu bahwa ||operator tidak akan bekerja dalam pernyataan kasus tetapi apakah ada hal serupa yang dapat saya gunakan.

Ankush
sumber
32
Menjadi pertanyaan mendasar menjadikannya sesuatu yang lebih layak untuk upvotes jika bukan duplikat karena sangat berguna. Dan itu adalah sesuatu yang tidak pernah terjadi pada saya sebisa mungkin, tetapi sekarang saya menyadari bahwa itu sangat jelas. Jadi semuanya Q & A yang cukup mengagumkan
Richard Tingle
1
@RichardTingle - apakah Anda terbiasa dengan Duff's Device - en.wikipedia.org/wiki/Duff%27s_device
user93353
4
"Mengapa begitu banyak upvotes? Cari" java switch "di internet dan baca salah satu dari ribuan penjelasan." <- menurutmu apa yang aku lakukan?
Brendan
4
Saya benar-benar mencari "beberapa kasus dalam satu baris java" dan T&J ini adalah hasil pertama.
domenix
1
Demo switch dalam jawaban yang dipilih dapat diulang kembali sekarang karena JDK-12 telah mengintegrasikan JEP-325. :)
Naman

Jawaban:

556

Anda dapat menggunakan kedua CASEpernyataan sebagai berikut.

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

LIHAT CONTOH INI: Contoh kode menghitung jumlah hari dalam bulan tertentu:

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);
    }
}

Ini adalah output dari kode:

Number of Days = 29

GAGAL:

Tempat menarik lainnya adalah pernyataan break. Setiap statemen break mengakhiri statemen switch terlampir. Aliran kontrol berlanjut dengan pernyataan pertama mengikuti blok sakelar. Pernyataan istirahat diperlukan karena tanpa mereka, pernyataan di blok switch fall through: Semua pernyataan setelah label kasus yang cocok dieksekusi secara berurutan, terlepas dari ekspresi label kasus berikutnya, sampai pernyataan istirahat ditemukan.

CONTOH KODE:

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);
            }
        }
    }
}

Ini adalah output dari kode:

August
September
October
November
December

Menggunakan Strings dalam pernyataan Switch

Di Java SE 7 dan yang lebih baru, Anda bisa menggunakan objek String dalam ekspresi statement switch. Contoh kode berikut,, menampilkan jumlah bulan berdasarkan nilai String yang bernama bulan:

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);
        }
    }
}

Output dari kode ini adalah 8.

DARI Java Docs

PSR
sumber
Oh oke. Itu mudah. Tidak tahu saya bisa melakukan itu
Ankush
18
Perlu disebutkan bahwa fitur bahasa ini disebut fallthrough. Casing tanpa breakdasarnya ditambahkan dengan case block berikutnya yang secara visual di bawah ini, maka jatuh .
Kaisar Orionii
5
@ Kobor42 pertama-tama pelajari cara berbicara di situs umum. Bagaimana saran Anda membantu, terima kasih. Terima kasih
PSR
1
@ Kobor42 Bagaimana dengan: Mengapa Anda menggunakan pemformatan itu? Menempatkan case secara horisontally membuat kode kurang dapat dibaca dan umumnya dianggap praktik buruk [Referensi opsional tetapi diinginkan]. Saya selalu merasa bahwa pernyataan switch adalah format yang sangat mudah dibaca tetapi disajikan dengan cara ini mereka kehilangan semua itu.
Richard Tingle
2
Demo switch dapat diulang sekarang karena JDK-12 telah mengintegrasikan JEP-325. :)
Naman
27

The casenilai-nilai hanya codeless "goto" poin yang dapat berbagi titik masuk yang sama:

case text1:
case text4: 
    //blah
    break;

Perhatikan bahwa kawat gigi itu berlebihan.

Bohemian
sumber
@trig lol. Saya melakukan hal semacam itu banyak akhir-akhir ini - menyalahkan mengetik jempol iPhone. Cheers
Bohemian
21

Kerjakan saja

case text1: case text4: 
     do stuff;
     break;
kaljak
sumber
15

Dengan integrasi JEP 325: Switch Expressions (Preview) di build akses awal JDK-12, orang sekarang dapat menggunakan bentuk baru label switch sebagai: -

case text1, text4 -> {
     //blah
} 

atau untuk mengulangi demo dari salah satu jawaban , seperti: -

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);
    }
}

Ini adalah bagaimana Anda dapat mencobanya - Kompilasi fitur pratinjau JDK12 dengan Maven

Naman
sumber
6

Kurung tidak perlu. Kerjakan saja

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

Jika ada yang penasaran, ini disebut kasus fallthrough. Kemampuan untuk melakukan ini adalah alasan mengapa break;perlu untuk mengakhiri pernyataan kasus. Untuk informasi lebih lanjut, lihat artikel wikipedia http://en.wikipedia.org/wiki/Switch_statement .

scottmrogowski
sumber
5

The fallthroughjawaban oleh orang lain adalah yang baik.

Namun pendekatan lain akan mengekstraksi metode dari isi laporan kasus Anda dan kemudian memanggil metode yang sesuai dari setiap kasus.

Pada contoh di bawah ini, kedua case 'text1' dan case 'text4' berperilaku sama:

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

Saya pribadi menemukan gaya penulisan pernyataan kasus ini lebih dapat dipertahankan dan sedikit lebih mudah dibaca, terutama ketika metode yang Anda panggil memiliki nama deskriptif yang baik.

Colin D
sumber
1
Tidak lebih dapat dipertahankan jika text1dan text4akan HAMPIR melakukan hal yang sama, terlepas dari perubahan di masa depan. Jika mereka harus selalu ditautkan, membuat perubahan dalam kasus untuk text1(artinya mengubah metode yang dipanggil) akan membutuhkan perubahan text4. Dalam hal ini jelas tidak lebih dapat dipertahankan. Itu tergantung situasi.
Nick Freeman
1
Saya akan mengatakan bahwa metode ini mungkin harus dikombinasikan dengan cara lain, karena pernyataan switch tidak (IMHO) struktur pemrograman tercantik.
Nick Freeman
5

Pendekatan fall through adalah yang terbaik yang kurasakan.

case text1:
case text4: {
        //Yada yada
        break;
} 
Ankur Sharma
sumber
5

Kamu bisa memakai:

case text1: case text4: 
     do stuff;
     break;
Joseph DSCS
sumber
4

Nilai case hanyalah titik "goto" tanpa kode yang dapat berbagi titik masuk yang sama:

case text1:
case text4: {
// Lakukan sesuatu yang
merusak;
}

Perhatikan bahwa kawat gigi itu berlebihan.

David_DD
sumber
1

JEP 354: Switch Expressions (Preview) di JDK-13 dan JEP 361: Switch Expressions (Standard) di JDK-14 akan memperluas pernyataan switch sehingga dapat digunakan sebagai ekspresi .

Sekarang kamu bisa:

  • langsung menetapkan variabel dari ekspresi switch ,
  • gunakan bentuk baru label sakelar ( case L ->):

    Kode di sebelah kanan label sakelar "case L ->" dibatasi menjadi ekspresi, blok, atau (untuk kenyamanan) pernyataan melempar.

  • gunakan beberapa konstanta per kasus, dipisahkan dengan koma,
  • dan juga tidak ada lagi pemutusan nilai :

    Untuk menghasilkan nilai dari ekspresi switch, breakpernyataan nilai dengan dijatuhkan demi suatu yieldpernyataan.

Jadi demo dari salah satu jawaban mungkin terlihat seperti ini:

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);
  }
}
Iskuskov Alexander
sumber