1つのswitch caseステートメントに2つの値を使用する


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

||演算子がcaseステートメントで機能しないことはわかっていますが、使用できる同様のものがあります。


32
基本的な質問であることは、広く役立つので重複していない場合、賛成投票に適格なものがあるかどうかを確認します。そして、それは可能な限り私には起こらなかったが、今や私はそれが盲目的に明白であることを理解した。つまり、全体的にかなり素晴らしいQ&A
Richard Tingle 2013年

1
@RichardTingle -あなたがダフのデバイスに精通している- en.wikipedia.org/wiki/Duff%27s_device
user93353

4
「なぜそれほど多くの賛成票があるのですか?インターネットで「javaスイッチ」を検索し、数千の説明の1つを読んでください。」<-私が何をしていたと思いますか?
ブレンダン

4
文字通り「1行のJavaで複数のケース」を検索したところ、このQ&Aが最初の結果でした。
domenix 2016

1
JDK-12がJEP-325を統合したので、選択した回答のスイッチのデモを言い換えることができます。:)
ナマン

回答:


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

フォールスルー:

もう1つの興味深い点は、breakステートメントです。各breakステートメントは、囲んでいるswitchステートメントを終了します。制御フローは、switchブロックに続く最初のステートメントから続行されます。breakステートメントが必要なのは、これらがない場合、switchブロックfall through内のステートメントです。breakステートメントが検出されるまで、後続のcaseラベルの式に関係なく、一致するcaseラベルの後のすべてのステートメントが順番に実行されます。

コード例:

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

switchステートメントでの文字列の使用

Java SE 7以降では、switchステートメントの式でStringオブジェクトを使用できます。次のコード例は、monthという名前の文字列の値に基づいて月の番号を表示します。

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ドキュメントから


ああ大丈夫。それは簡単でした。私がそれができるとは知りませんでした
アンクシュ2013年

18
この言語機能はフォールスルーと呼ばれていることを言及する価値があります。なしのケースにbreakは、基本的に視覚的に下にある次のケースブロックが追加されるため、失敗します。
Orionii皇帝

5
@ Kobor42はまず、公開サイトでの会話方法を学びます。あなたの提案がどのように役立つかを感謝します。ありがとう
PSR

1
@ Kobor42どうですか:なぜそのフォーマットを使用したのですか?ケースを水平に置くと、コードの可読性が低下し、一般に悪い習慣と見なされます[リファレンスはオプションですが、必要です]。switchステートメントは特に読みやすい形式であると常に感じていましたが、このように提示すると、それらはすべて失われます。
Richard Tingle 2013年

2
JDK-12にJEP-325が統合されたため、スイッチのデモは言い換えることができます。:)
ナマン


27

case値が同じエントリポイントを共有できるだけでコードレス「後藤」のポイントです。

case text1:
case text4: 
    //blah
    break;

ブレースは冗長であることに注意してください。


@trig lol。私は最近、そのようなことを頻繁に行っています-iPhoneのサムタイピングのせいです。乾杯
ボヘミアン


15

JEP 325の統合により、JDK-12初期アクセスビルドのスイッチ式(プレビュー)で、スイッチラベルの新しい形式を次のように使用できます。

case text1, text4 -> {
     //blah
} 

または、答えの1つからデモを言い換えると、次のようになります。

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

ここにあなたがそれを試すことができる方法があります-MavenでJDK12プレビュー機能をコンパイルしてください


6

ブラケットは不要です。するだけ

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

好奇心が強い場合、これはケースフォールスルーと呼ばれます。これを実行する機能が、break;ケースステートメントを終了する必要がある理由です。詳細については、ウィキペディアの記事http://en.wikipedia.org/wiki/Switch_statementを参照してください


5

fallthrough他人答えは良いものです。

ただし、別のアプローチは、caseステートメントのコンテンツからメソッドを抽出し、各ケースから適切なメソッドを呼び出すだけです。

以下の例では、ケース 'text1'とケース 'text4'の両方が同じように動作します。

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

特に、呼び出すメソッドにわかりやすい名前が付いている場合は、このスタイルのcaseステートメントを書く方が保守性が高く、読みやすくなります。


1
将来の変更に関係なく、ほぼ確実に同じことを行うかどうかはtext1、維持しtext4やすくありません。それらを常にリンクする必要がある場合、text1(それが呼び出すメソッドを変更することを意味する)のケースを変更するには、の変更が必要になりtext4ます。この場合、それは明らかにより保守可能ではありません。状況によります。
Nick Freeman

1
とにかく、この方法はおそらく逆の方法と組み合わせる必要があります。これは、switchステートメントが(IMHO)かわいらしいプログラミング構造ではないためです。
Nick Freeman



4

ケース値は、同じエントリポイントを共有できるコードレスの「goto」ポイントです。

case
text1 :case text4:{
//何か中断する
;
}

ブレースは冗長であることに注意してください。


1

JEP 354: JDK-13のスイッチ式(プレビュー)および JEP 361: JDK-14のスイッチ式(標準)は、 switchステートメントを拡張して、として使用できるようにします

今することができます:

  • スイッチ式から変数を直接割り当て、
  • 新しい形式のスイッチラベル(case L ->)を使用:

    "case L->"スイッチラベルの右側のコードは、式、ブロック、または(便宜上)throwステートメントに制限されています。

  • カンマで区切って、ケースごとに複数の定数を使用し、
  • また、これ以上の値の区切りはありません。

    switch式から値を生成するには、breakwith valueステートメントを削除してyieldステートメントを優先します。

したがって、回答の1つからのデモは次のようになります。

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.