Bir anahtar durum bildirimi için iki değer kullanma


297

Kodumda, program kullanıcı tarafından girilen metne bağlı olarak bir şey yapar. Kodum şöyle görünüyor:

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

Ancak, kod durumlarda text1ve text4aynıdır. Bu yüzden şöyle bir şey uygulamamın mümkün olup olmayacağını merak ediyordum

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

||Operatörün vaka ifadesinde çalışmayacağını biliyorum ama kullanabileceğim benzer bir şey var.


33
Temel bir soru olması, yaygın olarak yararlı bir kopya değilse, upvotes için daha uygun bir şey yaparsa. Ve bu benim için mümkün olmayan bir şeydi ama şimdi onun körü körüne açık olduğunu fark ettiğim için. Sonuçta oldukça harika bir Soru-Cevap
Richard Tingle

1
@RichardTingle - Duff'un Cihazını
biliyor musunuz

4
"Neden bu kadar çok oy veriyor?" İnternette "java switch" i arayın ve bin açıklamadan birini okuyun. " <- ne yaptığımı sanıyorsun?
Brendan

4
Kelimenin tam anlamıyla "bir satır java birden fazla vaka" aradım ve bu soru-cevap ilk sonuç oldu.
domenix

1
Seçilen yanıttaki anahtar demosu artık JDK-12'nin JEP-325'i entegre ettiği için yeniden ifade edilebilir . :)
Naman

Yanıtlar:


558

Her iki CASEifadeyi de aşağıdaki gibi kullanabilirsiniz .

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

BU ÖRNEĞİ GÖSTER: Kod örneği, belirli bir aydaki gün sayısını hesaplar:

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

Bu koddan çıktıdır:

Number of Days = 29

SUYA DÜŞMEK:

Bir diğer ilgi çekici nokta break ifadesidir. Her break ifadesi ek anahtar deyimini sonlandırır. Kontrol akışı, anahtar bloğunu izleyen ilk ifade ile devam eder. Break ifadeleri gereklidir, çünkü bunlar olmadan, anahtar bloklarındaki fall throughifadeler: Eşleşen vaka etiketinden sonraki tüm ifadeler, bir break ifadesi ile karşılaşılana kadar sonraki vaka etiketlerinin ifadesinden bağımsız olarak sırayla yürütülür.

ÖRNEK KOD:

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

Bu koddan çıktıdır:

August
September
October
November
December

Anahtar Deyimlerinde Dizeleri Kullanma

Java SE 7 ve sonraki sürümlerinde, switch ifadesinin ifadesinde bir String nesnesi kullanabilirsiniz. Aşağıdaki kod örneği, month adlı dizenin değerine göre ay sayısını görüntüler:

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

Bu koddan çıktı 8'dir.

Java Dokümanlarından


Ah tamam. Kolaydı. Bunu yapabileceğimi bilmiyordum
Ankush

18
Bu dil özelliğine geçiş adı verildiğini belirtmek gerekir. Olmayan vakalar breaktemelde görsel olarak aşağıda olan bir sonraki vaka bloğu ile eklenir, böylece düşer .
İmparator Orionii

5
Öneriniz yardım ful.Thanks nasıl Kobor42 @ ilk kamu sites.Any konuşmak öğrenmek
PSR

1
@ Kobor42 Nasıl olur: Bu biçimlendirmeyi neden kullandınız? Davaları yatay olarak koymak, kodu daha az okunabilir hale getirir ve genellikle kötü uygulama olarak kabul edilir [Referans isteğe bağlı ancak istenir]. Ben her zaman switch deyimleri özellikle okunabilir bir format olduğunu hissettim ama tüm bu kaybetmek bu şekilde sundu.
Richard Tingle

2
Anahtar demosu artık JDK-12'nin JEP-325'i entegre ettiği için yeniden ifade edilebilir . :)
Naman


27

caseDeğerler sadece aynı giriş noktası paylaşabilir "git" noktaları kodsuz:

case text1:
case text4: 
    //blah
    break;

Parantezlerin gereksiz olduğunu unutmayın.


@trig lol. Ben son zamanlarda bu tür bir şey yapıyorum - iPhone başparmak yazarak suçluyor. Şerefe
Bohemian

21

Sadece yap

case text1: case text4: 
     do stuff;
     break;

15

JDK-12 erken erişim yapılarına JEP 325: Anahtar İfadeleri (Önizleme) entegrasyonu ile artık anahtar etiketinin yeni formunu şu şekilde kullanabilirsiniz: -

case text1, text4 -> {
     //blah
} 

ya da demosu cevaplardan birinden yeniden ifade etmek için :

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

İşte bunu nasıl deneyebilirsiniz - Maven ile bir JDK12 önizleme özelliği derleyin


6

Köşeli ayraçlar gereksizdir. Sadece yap

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

Merak eden biri varsa, buna durumun son örneği denir. Bunu yapabilme yeteneği, break;vaka ifadelerini sona erdirmek için neden gereklidir. Daha fazla bilgi için http://en.wikipedia.org/wiki/Switch_statement wikipedia makalesine bakın .


5

fallthroughBaşkaları tarafından cevaplar iyi olanlardır.

Ancak başka bir yaklaşım, vaka ifadelerinizin içeriğinden yöntem ayıklamak ve daha sonra her bir durumdan uygun yöntemi çağırmak olacaktır.

Aşağıdaki örnekte, hem 'text1' durumu hem de 'text4' durumu aynı şekilde davranır:

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

Ben şahsen bu dava yazma tarzını, özellikle de çağırdığınız yöntemlerin tanımlayıcı isimleri iyi olduğunda daha sürdürülebilir ve biraz daha okunabilir buluyorum.


1
Gelecekte yapılacak bir değişiklik ne olursa olsun, aynı şeyi KESİNLİKLE YAPIYORSA text1ve text4sürdürecekse daha sürdürülebilir değildir . Her zaman bağlantılı olmaları durumunda, durumda bir değişiklik yapmak text1(hangi yöntemi çağırdığı anlamına gelir) değişiklik yapılması gerekir text4. Bu durumda, açıkça daha sürdürülebilir değildir. Bu duruma bağlıdır.
Nick Freeman

1
Anahtar deyimleri (IMHO) en güzel programlama yapısı olmadığı için bu yöntemin muhtemelen başka bir yolla birleştirilmesi gerektiğini söyleyeceğim.
Nick Freeman

5

Düşüş yaklaşımı en iyi hissediyorum.

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


4

Vaka değerleri sadece aynı giriş noktasını paylaşabilen kodsuz "git" noktalarıdır:

case
text1 : case text4: {
//
Mola vermek;
}

Parantezlerin gereksiz olduğunu unutmayın.


1

JEP 354: JDK-13'teki Anahtar İfadeleri (Önizleme) veJDK-14'teki Anahtar İfadeleri (Standart) , anahtar ifadesini ifade olarak kullanılabilmesi içingenişletir.

Şimdi yapabilirsin:

  • anahtar ifadesinden doğrudan değişken atayın ,
  • yeni bir switch label biçimi kullanın ( case L ->):

    Bir "case L ->" anahtar etiketinin sağındaki kod, bir ifade, bir blok ya da (kolaylık olması açısından) bir throw ifadesi ile sınırlıdır.

  • virgülle ayrılmış durumda her durumda birden çok sabit kullanın,
  • ve daha fazla değer sonu yok :

    Bir anahtar ifadesinden bir değer vermek için breakwith value ifadesi, bir yieldifade lehine bırakılır .

Cevaplardan birinin demosu şöyle görünebilir:

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);
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.