Utilizzo di due valori per un'istruzione case switch


296

Nel mio codice, il programma fa qualcosa a seconda del testo inserito dall'utente. Il mio codice è simile a:

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

Tuttavia, il codice all'interno di casi text1ed text4è lo stesso. Mi chiedevo quindi se sarebbe stato possibile implementare qualcosa del genere

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

So che l' ||operatore non funzionerà nell'affermazione del caso, ma c'è qualcosa di simile che posso usare.


32
Essere una domanda di base lo rende se qualcosa di più ammissibile per i voti se non è un duplicato in quanto ampiamente utile. Ed è qualcosa che non mi è accaduto possibile, ma ora che me ne rendo conto è accecantemente ovvio. Quindi, tutto sommato, un fantastico D&R
Richard Tingle,

1
@RichardTingle - hai familiarità con il dispositivo di Duff - it.wikipedia.org/wiki/Duff%27s_device
user93353

4
"Perché così tanti voti positivi? Cerca" java switch "in Internet e leggi una delle mille spiegazioni." <- cosa pensi che stavo facendo?
Brendan,

4
Ho letteralmente cercato "più casi in una riga java" e questo è stato il primo risultato.
domenix,

1
La demo dell'interruttore nella risposta selezionata potrebbe essere riformulata ora che JDK-12 ha integrato JEP-325. :)
Naman,

Risposte:


556

Puoi usare entrambe le CASEistruzioni come segue.

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

VEDI QUESTO ESEMPIO: l'esempio di codice calcola il numero di giorni in un determinato mese:

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

Questo è l'output del codice:

Number of Days = 29

SFUMARE:

Un altro punto di interesse è la dichiarazione di rottura. Ogni istruzione break termina l'istruzione switch inclusa. Il flusso di controllo continua con la prima istruzione che segue il blocco interruttore. Le istruzioni di interruzione sono necessarie perché senza di esse, istruzioni in blocchi di interruttori fall through: tutte le istruzioni dopo l'etichetta del caso corrispondente vengono eseguite in sequenza, indipendentemente dall'espressione delle successive etichette del caso, fino a quando non viene rilevata un'istruzione di interruzione.

CODICE DI ESEMPIO:

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

Questo è l'output del codice:

August
September
October
November
December

Utilizzo delle stringhe nelle istruzioni switch

In Java SE 7 e versioni successive, è possibile utilizzare un oggetto String nell'espressione dell'istruzione switch. L'esempio di codice seguente mostra il numero del mese in base al valore della stringa denominata mese:

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

L'output di questo codice è 8.

DA Java Docs


Oh va bene. È stato facile. Non sapevo che avrei potuto farlo
Ankush,

18
Vale la pena ricordare che questa funzione del linguaggio è chiamata fallthrough. I casi senza breakvengono sostanzialmente aggiunti al blocco del caso successivo che è visivamente sotto, quindi fallisce .
Imperatore Orionii

5
@ Kobor42 prima impara a parlare in siti pubblici. Qualunque sia il tuo suggerimento è di aiuto. Grazie
PSR

1
@ Kobor42 Che ne dici di: Perché hai usato quella formattazione? Mettere i casi in modo orizzontale rende il codice meno leggibile ed è generalmente considerato una cattiva pratica [riferimento facoltativo ma desiderato]. Ho sempre pensato che le istruzioni switch siano un formato particolarmente leggibile, ma presentate in questo modo perdono tutto ciò.
Richard Tingle,

2
La demo dello switch potrebbe essere riformulata ora che JDK-12 ha integrato JEP-325. :)
Naman,


27

I casevalori sono solo punti "goto" senza codice che possono condividere lo stesso punto di ingresso:

case text1:
case text4: 
    //blah
    break;

Si noti che le parentesi graffe sono ridondanti.


@trig lol. Ultimamente sto facendo questo genere di cose: incolpare la tipizzazione con il pollice di iPhone. Saluti
Boemo

21

Basta fare

case text1: case text4: 
     do stuff;
     break;

15

Con l'integrazione di JEP 325: Switch Expressions (Anteprima) nelle build di accesso anticipato JDK-12, è ora possibile utilizzare la nuova forma dell'etichetta switch come: -

case text1, text4 -> {
     //blah
} 

o per riformulare la demo da una delle risposte , qualcosa del tipo:

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

Ecco come puoi provarlo: compila una funzione di anteprima JDK12 con Maven


6

Le parentesi non sono necessarie. Basta fare

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

Se qualcuno è curioso, questo è chiamato caso fallthrough. La capacità di farlo è il motivo per cui break;è necessario terminare le dichiarazioni dei casi. Per ulteriori informazioni, consultare l'articolo di Wikipedia http://it.wikipedia.org/wiki/Switch_statement .


5

Le fallthroughrisposte degli altri sono buone.

Tuttavia, un altro approccio sarebbe quello di estrarre metodi dal contenuto delle dichiarazioni del caso e quindi chiamare il metodo appropriato da ciascun caso.

Nell'esempio seguente, sia il caso 'text1' che il caso 'text4' si comportano allo stesso modo:

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

Personalmente trovo questo stile di scrittura delle dichiarazioni dei casi più gestibile e leggermente più leggibile, specialmente quando i metodi che chiami hanno buoni nomi descrittivi.


1
Non è più mantenibile se text1e text4QUASI Sicuramente farà la stessa cosa, indipendentemente da un cambiamento futuro. Se devono essere sempre collegati, apportare una modifica al caso text1(ovvero cambiare il metodo che chiama) richiederebbe una modifica text4. In questo caso ovviamente non è più mantenibile. Dipende dalla situazione.
Nick Freeman,

1
Dirò che questo metodo dovrebbe probabilmente essere combinato comunque con l'altro, poiché le istruzioni switch non sono (IMHO) la struttura di programmazione più bella.
Nick Freeman,

5

Fall attraverso l'approccio è il migliore che sento.

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


4

I valori del caso sono solo punti "goto" senza codice che possono condividere lo stesso punto di ingresso:

case text1:
case text4: {
// Fai qualcosa di
rotto;
}

Si noti che le parentesi graffe sono ridondanti.


1

JEP 354: Switch Expressions (anteprima) in JDK-13 e JEP 361: Switch Expressions (standard) in JDK-14 estenderanno l' istruzione switch in modo che possa essere utilizzata come espressione .

Ora puoi:

  • assegnare direttamente la variabile dall'espressione switch ,
  • usa una nuova forma di etichetta switch ( case L ->):

    Il codice a destra di un'etichetta switch "case L ->" è limitato a un'espressione, un blocco o (per comodità) un'istruzione di lancio.

  • usa più costanti per caso, separate da virgole,
  • e inoltre non ci sono più interruzioni di valore :

    Per ottenere un valore da un'espressione switch, l' breakistruzione with value viene eliminata a favore di yieldun'istruzione.

Quindi la demo di una delle risposte potrebbe apparire così:

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);
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.