こんにちは。今回はJavaのswitch文についてです。大まかにいうと、この構文では式の値で処理を分岐する記述ができます。使える式のひとつとして、int型変数があります。今回はint型変数を使って、分岐処理のサンプルを作りました。
この記事の前半でswitch文の基本形を扱いました。その後、複数の値で同じ処理を実行したい場合の記述方法についての説明を書きました。最後にfor文の内側でswitch文を使ったサンプルを作りました。
switch文を使う状況
例として、ある大会の参加者の順位がデータとしてあるとします。参加者に対して、順位に応じたメッセージを作るという処理を考えます。メッセージは以下のように順位に応じて作成するものとします。
順位 | メッセージ |
---|---|
1 | 優勝です。 |
2 | 準優勝です。 |
それ以外 | ご参加ありがとうございました。 |
今回はMyMsgクラスを新規作成し、上記のようにメッセージを返却するメソッドを作るとします。メソッドは仮引数をint型変数、戻り値はString型にして、以下のように作るとします。
メソッド | 説明 |
---|---|
public static String create(int rank) | 仮引数rankの値に応じてメッセージを生成する。 |
- パラメータ:
rank
– 順位- 戻り値:
- メッセージ
インスタンスの生成は特に必要ないので、staticメソッドとしています。
switch文の記述の仕方
前述のメソッドを以下のように実装することにします。
-
ローカル変数を宣言する。
型 変数名 初期値 String msg null
-
以下の分岐処理をする。
仮引数rankの値の条件 処理内容 分岐(1) 1の場合
msg
←"優勝です。"
分岐(2) 2の場合
msg
←"準優勝です。"
分岐(3) それ場合
msg
←"ご参加ありがとうございました。"
-
msg
を返却する。
上記の分岐処理を実装するためにswitch文を使います。構文の記述方法は以下です。
ソース
switch ([int型変数]) {
case [値1]:
[処理1]
break;
case [値2]:
[処理2]
break;
default:
[デフォルト処理]
break;
}
「case [値1]」、「case [値2]」はcaseラベルと呼ばれます。switch文では[int型変数]の値に等しいcaseラベルがある場合、その行に処理がジャンプします。その行からbreakが現れるまで順番に処理が実行されます。
「default」はdefaultラベルと呼ばれます。[int型変数]の値に等しいcaseラベルが存在しない場合、defaultラベルに処理がジャンプします。
処理の進み方を簡易的な表にすると以下です。
[int型変数]の値 | |||
---|---|---|---|
[値1] | [値2] | それ以外の場合 | |
[処理1] | 実行される | ||
[処理2] | 実行される | ||
[デフォルト処理] | 実行される |
今回は上記の記述方法を使って、以下のように処理を実装しました。
ソース
public class MyMsg {
/**
* 仮引数rankの値に応じてメッセージを生成する。
*
* @param rank 順位
* @return メッセージ
*/
public static String create(int rank) {
String msg = null;
switch (rank) {
case 1: // (1)
msg = "優勝です。";
break;
case 2: // (2)
msg = "準優勝です。";
break;
default: // (3)
msg = "ご参加ありがとうございました。";
break;
}
return msg;
}
}
上記のメソッドでは、仮引数rankをswitch文の式に指定しています。
変数rankの値が1の場合、(1)の箇所に処理がジャンプします。その後、breakが現れるまで順番に処理が実行されます。上記の場合はmsgに”優勝です。”が格納されます。
変数rankの値が2の場合、(2)の箇所に処理がジャンプします。後は(1)の場合と同様にbreakが現れるまで順番に処理が実行されます。
変数rankの値が1でも2でもない場合、ジャンプするべきcase文がありません。その場合、(3)のdefaultに処理がジャンプします。その後、breakが現れるまで処理が順番に実行されます。最後のbreakはなくても問題ないと思いますが、Eclipseの補完機能ではbreakが保管されました。
上記コードの動作を以下のテスト用クラスで確認しました。
動作確認
public class MyMsgTest {
public static void main(String[] args) {
int rank = 1;
System.out.println(rank + "..." + MyMsg.create(rank));
rank = 2;
System.out.println(rank + "..." + MyMsg.create(rank));
rank = 3;
System.out.println(rank + "..." + MyMsg.create(rank));
rank = 99;
System.out.println(rank + "..." + MyMsg.create(rank));
}
}
結果
1...優勝です。
2...準優勝です。
3...ご参加ありがとうございました。
99...ご参加ありがとうございました。
実引数が1と2の場合、それぞれのcase文に処理がジャンプしたことがわかります。
実引数が3と99の場合はdefaultに処理がジャンプしたことがわかります。
このように、switch文でint型変数の値に応じた分岐処理を記述できます。
breakを記述しない場合の動作
上述のswitch文の記述では、case文に対応してbreakを記述していますが、分岐処理のさせ方次第では、breakを記述しない場合があります。
メッセージを以下のように生成するとします。
順位 | メッセージ |
---|---|
1 | 優勝です。 |
2 | 準優勝です。 |
3~5 | 頑張りました。 |
それ以外 | ご参加ありがとうございました。 |
上記のように順位が3~5の場合に同じメッセージを生成するとします。このような場合、以下のようにcase文を並べることで、分岐処理を実装できます。
ソース
public class MyMsg2 {
/**
* 仮引数rankの値に応じてメッセージを生成する。
*
* @param rank 順位
* @return メッセージ
*/
public static String create(int rank) {
String msg = null;
switch (rank) {
case 1:
msg = "優勝です。";
break;
case 2:
msg = "準優勝です。";
break;
case 3:
case 4:
case 5:
msg = "頑張りました。"; // (1)
break;
default:
msg = "ご参加ありがとうございました。";
break;
}
return msg;
}
}
変数rankが3の場合、「case 3」の行に処理がジャンプします。break文が現れるまで順番に処理されるので、(1)が実行されます。その直後のbreakでswitch文が終了します。途中で現れる「case 4」、「case 5」はラベルなので処理はありません。
変数rankが4、5の場合、それぞれ「case 4」、「case 5」の行に処理がジャンプします。「case 3」の場合と同様に(1)が実行されます。
上記サンプルプログラムを、以下のように動作確認しました。
動作確認
public class MyMsg2Test {
public static void main(String[] args) {
int rank = 1;
System.out.println(rank + "..." + MyMsg2.create(rank));
rank = 2;
System.out.println(rank + "..." + MyMsg2.create(rank));
rank = 3;
System.out.println(rank + "..." + MyMsg2.create(rank));
rank = 4;
System.out.println(rank + "..." + MyMsg2.create(rank));
rank = 5;
System.out.println(rank + "..." + MyMsg2.create(rank));
rank = 6;
System.out.println(rank + "..." + MyMsg2.create(rank));
rank = 99;
System.out.println(rank + "..." + MyMsg2.create(rank));
}
}
結果
1...優勝です。
2...準優勝です。
3...頑張りました。
4...頑張りました。
5...頑張りました。
6...ご参加ありがとうございました。
99...ご参加ありがとうございました。
上記結果のように、実引数が3,4,5の場合、同じ内容が出力されています。
このように、switch文でbreakを記述しない方法で複数の値に同じ分岐処理を実行することができます。
for文とswitch文を組み合わせたサンプル
ここではfor文の内側でswitch文を使ったサンプルを紹介します。処理の理解のためのサンプルです。内容は数当て遊び的なものです。
以下にフローを書きます。
-
繰り返しカウンタ1が1から9まで以下を繰り返す。
-
文字列型変数sを以下の値で初期化する。
[繰り返しカウンタ1] + “回目 “
-
繰り返しカウンタ1の値で以下のようにsの末尾に文字列を追加する。
iの値 追加する文字列 5 当たり 4,6 近い 3,7 まあまあ近い 上記以外 遠い
-
- sをprintlnで出力する。
以下はソースと実行結果です。
ソース
public class Sample {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
String s = i + "回目 ";
switch (i) {
case 5:
s += "当たり";
break;
case 3:
case 7:
s += "まあまあ";
case 4:
case 6:
s += "近い";
break;
default:
s += "遠い";
break;
}
System.out.println(s);
}
}
}
結果
1回目 遠い
2回目 遠い
3回目 まあまあ近い
4回目 近い
5回目 当たり
6回目 近い
7回目 まあまあ近い
8回目 遠い
9回目 遠い
for文で繰り返し変数iを使って、処理を10回繰り返しています。
for文の内側で、switch文で変数iの値に応じて文字列を設定しています。
変数iの値が3か7の場合の分岐では、breakは使ってません。そのため、変数sに”まあまあ”が追加され、さらに”近い”が追加されます。そのため、出力結果のように、文字列”まあまあ近い”が出力されます。
以上、参考になれば幸いです。