#目的
Java言語を含めたプログラミングの学習を始めたばかりの方、既学習者の方は復習用に、
今回は条件分岐について学ぶために書いています。
【Java入門目次】
・変数と型
・型変換
・変数のスコープ
・文字列の操作
・配列の操作
・演算子
・条件分岐 ←今ここ
・繰り返し処理
・クラスについて(準備中)
・抽象クラス(準備中)
・インターフェース(準備中)
・カプセル化(準備中)
・モジュールについて(準備中)
・例外処理について
・ラムダ式について
・Stream APIについて
#条件分岐とは
ソースコード内である条件が満たされているかによって実行する処理を分けることです。
もし、〇〇ならばAの処理、△△ならばBの処理をする。
といった感じです。
#if文
条件式をもち、その条件の結果に応じた処理を行う場合に使用します。
条件式の結果はboolean値(true、false)
で返ってきて、trueの時にif文内の処理が実行されます。
if( 条件式 ) {
処理
};
例えば、条件式がtrueの場合。
int num = 10;
if (num < 20) {
System.out.println("numの値は20未満");
}
System.out.println("if文後の処理");
実行結果は以下になります。
numの値は20未満
if文後の処理
条件式を判定、結果はtrueなので、if文ブロック内の処理が実行され、その後、ifブロック外の処理が実行される。という流れになります。
条件式がfalseの場合。
int num = 10;
if (num < 5) {
System.out.println("numの値は5未満");
}
System.out.println("if文後の処理");
実行結果は以下になります。
if文後の処理
条件式がfalseなのでif文ブロック内の処理が実行されず、その後の処理だけ実行されています。
また、if文の中にif文を記述する事も可能です。**ネスト(入れ子)**と言います。
ただ、あまり複数記述すると読みにくくなるので気をつけましょう。
int num = 10;
if (num > 0) {
System.out.println("numは正の値");
if (num % 2 == 0) {
System.out.println("numは偶数");
}
}
##値の比較時の注意
値が同じであるかを比較するには、==
と記述します。=
が1つだけの場合、関係演算子ではなく代入演算子になるので注意しましょう。
以下はコンパイルエラーになります。
int a = 20;
int b = 50;
if (a = b) { // int型のaにbを代入しているだけで、条件式が成り立っていない
System.out.println("aとbの値は同じ");
}
値の比較は以下の様にします。
int a = 50;
int b = 50;
if (a == b) {
System.out.println("aとbの値は同じ");
}
aとbの値は同じ
条件式の箇所で代入を行ってもコンパイルエラーにはならないパターンもあります。
boolean bool1 = false;
boolean bool2 = true;
if(bool1 = bool2) { // 代入の結果、boolean値が返ってくるので条件式として問題ない
System.out.println("bool1: " + bool1);
System.out.println("bool2: " + bool2);
}
falseのbool1にtrueのbool2を代入した結果、条件式がtrueになります。
よって、if文ブロック内の処理が実行されます。
bool1: true
bool2: true
#if-else文
条件式がtrueの時だけではなく、falseの時に行いたい処理を記述し、実行する事もできます。
if( 条件式 ) {
処理1
} else {
処理2
};
処理1は条件式がtrueの時に実行され、処理2は条件式がfalseの時に実行されます。
例えば、条件式がtrueの場合。
String name1 = "柳田";
String name2 = "柳田";
if (name1 == name2) {
System.out.println("name1とname2は同じ");
} else {
System.out.println("name1とname2は同じではない");
}
System.out.println("if-else文後の処理");
実行結果は以下になります。
name1とname2は同じ
if-else文後の処理
条件式がtrueなのでif文ブロック内の処理が実行されます。
そして、elseブロック内は実行されず、if文ブロック外の処理が実行される。という流れになります。
条件式がfalseの場合。
String name1 = "クリスティアーノ・ロナウド";
String name2 = "リオネル・メッシ";
if (name1 == name2) {
System.out.println("name1とname2は同じ");
} else {
System.out.println("name1とname2は同じではない");
}
System.out.println("if-else文後の処理");
実行結果は以下になります。
name1とname2は同じではない
if-else文後の処理
条件式がfalseなのでif文ブロック内の処理が実行されず、else文ブロックの処理が実行されています。
そして、if文ブロック外の処理が実行される。という流れになります。
これで条件式がfalseの場合の処理を実装することが出来ます。
#else if文
今までは条件式が1つだけでしたが、else if文を用いる事で複数の条件式を使うことが出来ます。
if( 条件式1 ) {
処理1
} else if ( 条件式2 ) {
処理2
} else {
処理3
};
処理1は条件式1がtrueの時に実行され、処理2は条件式2がtrueの時に実行され、処理3は1つ目と2つ目の条件式がfalseの時に実行されます。
else if文は上から順に条件式が評価され、ある条件がtrueであった場合にそのブロック内の処理文のみを実行します。
例えば、条件式ifがtrueの場合。
String color = "red";
if (color == "red") {
System.out.println("colorはred");
} else if (color == "yellow") {
System.out.println("colorはyellow");
} else {
System.out.println("colorはredでもyellowでもない");
System.out.println("colorは" + color);
}
System.out.println("else ifの例");
実行結果は以下になります。
colorはred
else ifの例
1つ目の条件式がtrueなのでif文ブロック内の処理が実行されます。
そして、else if、elseブロック内は実行されず、if文ブロック外の処理が実行される。という流れになります。
次に、条件式else ifがtrueの場合。
String color = "yellow";
if (color == "red") {
System.out.println("colorはred");
} else if (color == "yellow") {
System.out.println("colorはyellow");
} else {
System.out.println("colorはredでもyellowでもない");
System.out.println("colorは" + color);
}
System.out.println("else ifの例");
実行結果は以下になります。
colorはyellow
else ifの例
1つ目の条件式がfalseなのでif文ブロック内の処理が実行されません。
そして、2つ目の条件式がtrueなのでelse if文ブロック内の処理が実行されます。
elseブロック内は実行されず、if文ブロック外の処理が実行される。という流れになります。
最後に条件式の全てがfalseの場合。
String color = "blue";
if (color == "red") {
System.out.println("colorはred");
} else if (color == "yellow") {
System.out.println("colorはyellow");
} else {
System.out.println("colorはredでもyellowでもない");
System.out.println("colorは" + color);
}
System.out.println("else ifの例");
実行結果は以下になります。
colorはredでもyellowでもない
colorはblue
else ifの例
1つ目、2つ目と条件式の結果がfalseなので、elseブロック内の処理が実行されます。
そして、if文ブロック外の処理が実行される。という流れになります。
これで複数の条件判定によって処理を分けることが出来るようになります。
#三項演算子
条件式の結果に応じた式を実行する演算子です。
条件式 ? 式1 : 式2;
条件式がtrueを返した場合は式1を実行し、falseを返した場合は式2を実行します。
例えば、条件式がtrueの場合。
String name = "yamada";
String str = "名前の長さは";
str += name.length() >= 4 ? "4以上です" : "3以下です";
System.out.println(str);
実行結果は以下になります。
名前の長さは4以上です
name.length() >= 4
が条件式になります。
trueであれば、4以上です
が、falseであれば3以下です
がstrに格納されている文字列と結合されます。
同じ処理をif-else文で記述すると以下の様になります。
String name = "yamada";
String str = "名前の長さは";
if (name.length() >= 4) {
str += "4以上です";
} else {
str += "3以下です";
}
System.out.println(str);
三項演算子の方がif-else文で記述するよりスッキリ書けますね。
#switch文
式の評価結果と定数を比較して、一致した場合に処理が実行される。という多分岐処理を行うための方法です。
switch ( 式 ) {
case 定数1:
処理1;
break;
case 定数2:
処理2;
break;
default:
処理3;
}
式の結果が定数1と一致していれば処理1が実行され、定数2と一致していれば処理2が実行されます。
一致するものがない場合、default以下の処理が実行されます。(defaultの記述は任意です)
String color = "blue";
switch (color) {
case "red":
System.out.println("colorはred");
break;
case "yellow":
System.out.println("colorはyellow");
break;
case "blue":
System.out.println("colorはblue");
break;
default:
System.out.println("colorは" + color);
break;
}
実行結果は以下になります。
colorはblue
式の結果は"blue"という文字列であり、3つ目のcaseと一致しています。
よって、その中の処理が実行されます。
##switch文の注意点
###式のデータ型
switch文の式に記述可能な値は、char、byte、short、int、そのラッパークラス、enum、Stringのいずれかのデータ型の値ではないといけません。
それ以外の型が指定されているとコンパイルエラーになります。
double d = 2.0;
switch (d) { // Cannot switch on a value of type double. Only convertible int values, strings or enum variables are permitted
// 省略
}
###式の結果
式のデータ型を守っていたとして式の結果がnullであった場合、コンパイルは成功しても実行時に例外が発生してしまいます。
String ex = null;
switch (ex) {
case "a":
System.out.println("a");
break;
case "b":
System.out.println("b");
break;
default:
System.out.println("nothing");
break;
}
Exception in thread "main" java.lang.NullPointerException
at Condition.main(Condition.java:102)
###()内で演算子を使う
()内で計算をしても問題はないです。
足し算や、
int a = 0;
switch (a + 1) {
case 0:
System.out.println("0");
break;
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
}
1
デクリメントなど。
int a = 0;
switch (--a) {
case 0:
System.out.println("0");
break;
case 1:
System.out.println("1");
break;
default:
System.out.println("該当数字はないです");
break;
}
該当数字はないです
ただ、()内で変数を宣言するとコンパイルエラーになります。
switch (int a = 0;) {
case 0:
System.out.println("0");
break;
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
}
###caseで指定する値
①式の結果のデータ型とcaseで指定しているデータ型が一致していなければコンパイルエラーとなります。
int num = 10;
switch (num) {
case "0": // Type mismatch: cannot convert from String to int
System.out.println("0");
break;
case "1": // Type mismatch: cannot convert from String to int
System.out.println("1");
break;
case "2": // Type mismatch: cannot convert from String to int
System.out.println("2");
break;
}
②リテラル、定数ではない場合、コンパイルエラーとなります。
int num = 10;
int a = 1;
int b = 2;
switch (num) {
case a: // case expressions must be constant expressions
System.out.println("1");
break;
case b: // case expressions must be constant expressions
System.out.println("2");
break;
default:
System.out.println("nothing");
break;
}
この場合、変数であるaとbをcaseに指定しているためエラーになります。
final修飾子を付与して定数化するか、リテラルを指定しましょう。
int num = 10;
final int a = 1;
switch (num) {
case a:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
default:
System.out.println("nothing");
break;
}
③nullを指定するとコンパイルエラーとなります。
String name = "田中";
switch (name) {
case "山田":
System.out.println("山田");
break;
case null: // case expressions must be constant expressions
System.out.println("null");
break;
}
④break文の有無
**break;**というワードで、処理が実行された後にswitch文から抜けています。
もし忘れてしまっていた場合は次のcaseとの比較を初めてしまうので気をつけましょう。
int num = 10;
switch (num) {
case 0:
System.out.println("0");
break;
case 10:
System.out.println("10");
// break;を書き忘れている
default:
System.out.println("nothing");
break;
}
case 10 の時の処理が実行された後、break文がないためdefaultの処理も実行してしまいます。
10
nothing
意図せぬ実行結果になってしまわないよう注意しましょう。
#終わりに
プログラムの処理手順として条件に応じて処理を分岐させる方法を学びました。
ソースコードの可読性などを考慮して、状況によって使い分けていきたいですね。
#参考サイト