【Java】条件分岐

2022年1月9日

本稿では条件分岐について説明します。

プログラムにおいて、条件分岐は最も重要な要素です。

数値が50だったらこの処理を実行し、以外は別の処理を実行したい場合などに利用します。

例えば、お金が100以上あれば銅の剣を購入できるが100未満であれば購入できない、といったことを処理する時などがあげられます。

条件演算子を利用し、真か偽かを取得する

まずは条件分岐をさせる前に、比較演算子について覚えましょう。

演算子 説明
> 左辺が右辺よりも大きい場合に真となる
>= 左辺が右辺よりも大きい等しい場合に真となる
< 左辺が右辺よりも小さい場合に真となる
<= 左辺が右辺よりも小さい小さいか等しい場合に真となる
== 左辺が右辺と等しい場合に真となる
!= 左辺が右辺と等しくない場合に真となる
instanceof 左辺が右辺と同じクラスか右辺のサブクラス、または親クラスである場合に真となる

値型の比較は値で比較されますが、参照型の比較は参照先の値ではなくアドレス(番地)で比較されますので注意しましょう。

instanceofに関しては、ほとんど使用しないので今は覚えなくても問題ないです。

それでは、比較処理を実行して真か偽かを取得するサンプルをご覧ください。

public class Test{
	public static void main(String[] args){
		int gold = 50;
		boolean isOK = (gold >= 100);
		System.out.println(isOK);
	}
}
実行結果

false

4行目でgoldが100以上かどうかを取得しています。
今回はgoldが50なので結果が偽となりfalseが表示されました。

ではgoldを100以上にしてみましょう。

public class Test{
	public static void main(String[] args){
		int gold = 200;
		boolean isOK = (gold >= 100);
		System.out.println(isOK);
	}
}
実行結果

true

次はgoldが100以上になったので結果が真となりtrueが表示されました。

AND条件、OR条件、否定条件を行う演算子

~かつ~ならば~や~または~なら~のような複数の条件でtrue、falseを取得する事もできます。
また、比較結果の反転を行う演算子も存在します。
&& と || を使用する際には、優先順位にも気を付けましょう。&&演算子のほうが優先して実行されます。

演算子 説明
&& 左辺と右辺が真なら真となる
|| 左辺か右辺が真なら真となる
! 真なら偽に、偽なら真となる

それではAND条件、OR条件、否定のサンプルを一気に見てみましょう。

public class Test{
	public static void main(String[] args){
		int hp = 100;
		int mp = 25;
		boolean isHpNotMp = (hp == 100 && mp != 50);//AND条件
		boolean isHpOrMp = (hp == 100 || mp == 50);//OR条件
		boolean isNotHp = !(hp == 100);//比較結果の否定
		boolean isHpOrMpOrMpAndMp = (hp == 90 || mp == 25 || mp == 25 && mp == 50);//&&と||は&&条件が先に処理される。
		boolean isHpOrMpOrMpAndMp2 = ((hp == 90 || mp == 25 || mp == 25) && mp == 50);//優先したい処理はカッコで囲む
		System.out.println(hp+" == 100 && "+mp+" != 50:"+isHpNotMp);
		System.out.println(hp+" == 100 || "+mp+" == 50:"+isHpOrMp);
		System.out.println("!("+hp+" == 100):"+isNotHp);
		System.out.println(hp+" == 90 || "+mp+" == 25 || "+mp+" == 25 && "+mp+" == 50:"+isHpOrMpOrMpAndMp);
		System.out.println("("+hp+" == 90 || "+mp+" == 25 || "+mp+" == 25) && "+mp+" == 50:"+isHpOrMpOrMpAndMp2);
	}
}
実行結果

100 == 100 && 25 != 50:true
100 == 100 || 25 == 50:true
!(100 == 100):false
100 == 90 || 25 == 25 || 25 == 25 && 25 == 50:true
(100 == 90 || 25 == 25 || 25 == 25) && 25 == 50:false

文字列の比較

文字列の比較は==演算子でしないようにしましょう。変数の定義の記事で説明しましたが、文字列は参照型です。参照型を==演算子で比較すると、値の比較ではなく、番地の比較になってしまうのです。

番地が同じ場合であれば==演算子で比較できるのですが、ちょっとした処理を入れるだけで番地が変わってしまいます。

実際に==で比較できないサンプルコードを紹介します。

public class Test{
	public static void main(String[] args){
		String s1 = "あいうえお";
		String s2 = "あいうえお".replace("あ","あ");
		boolean isSame = s1 == s2;
		System.out.println(s1+"=="+s2+":"+isSame);
	}
}
実行結果

あいうえお==あいうえお:false

文字列の値が同じなのでここではtrueが返ってきて欲しいのですが、falseとなってしまいました。

Javaの文字列比較で値の比較がしたい場合は通常Stringクラスのequalsメソッドを使用します。メソッド自体についての解説は別の記事でするので、ここではこう書けば比較できるとだけ覚えてもらえれば問題ないです。

それでは比較部分をequalsメソッドを利用した処理に変えてみましょう。

public class Test{
	public static void main(String[] args){
		String s1 = "あいうえお";
		String s2 = "あいうえお".replace("あ","あ");
		boolean isSame = s1.equals(s2);
		System.out.println(s1+"=="+s2+":"+isSame);
	}
}
実行結果

あいうえお==あいうえお:true

これで望み通りの結果になりました。

if文else if文else文

それでは実際に条件分岐で処理を分岐させてみたいと思います。
条件分岐はif文を使用します。
if ( 分岐条件 ) {
//真だった場合に実行する処理
}

それでは、サンプルをご覧ください。

public class Test{
	public static void main(String[] args){
		int gold = 150;
		boolean isOK = (gold >= 100);
		if ( isOK ) {
			System.out.println("銅の剣を購入できました。");
		}
		System.out.println("冒険にでかけました。");
	}
}
実行結果

銅の剣を購入できました。
冒険にでかけました。

では、100未満にして実行してみましょう。

public class Test{
	public static void main(String[] args){
		int gold = 50;
		boolean isOK = (gold >= 100);
		if ( isOK ) {
			System.out.println("銅の剣を購入できました。");
		}
		System.out.println("冒険にでかけました。");
	}
}
実行結果

冒険にでかけました。

このように条件が真の時のみ購入の処理ができているのがわかるかと思います。


else文を使用するとそれ以外の処理を実行できます。
それではelse文のサンプルです。

public class Test{
	public static void main(String[] args){
		int gold = 50;
		boolean isOK = (gold >= 100);
		if ( isOK ) {
			System.out.println("銅の剣を購入できました。");
		} else {
			System.out.println("お金がないので購入できません。");
		}
	}
}
実行結果

お金がないので購入できません。

では、100以上にして実行してみましょう。

public class Test{
	public static void main(String[] args){
		int gold = 550;
		boolean isOK = (gold >= 100);
		if ( isOK ) {
			System.out.println("銅の剣を購入できました。");
		} else {
			System.out.println("お金がないので購入できません。");
		}
	}
}
実行結果

銅の剣を購入できました。

このように条件によって処理の分岐ができているのがわかるかと思います。


if ( 比較条件 ) のように直接条件を記述することもできます。こっちのほうが主流かな?

public class Test{
	public static void main(String[] args){
		int gold = 100;
		if ( gold >= 100 ) {
			System.out.println("銅の剣を購入できました。");
		} else {
			System.out.println("お金がないので購入できません。");
		}
	}
}
実行結果

銅の剣を購入できました。


else if 文を使用することで複数の条件分岐を実行させることができます。

public class Test{
	public static void main(String[] args){
		int gold = 600;
		if ( gold >= 1000 ) {
			System.out.println("白金の剣を購入できました。");
		} else if ( gold >= 500 ) {
			System.out.println("金の剣を購入できました。");
		} else if ( gold >= 300 ) {
			System.out.println("銀の剣を購入できました。");
		} else if ( gold >= 100 ) {
			System.out.println("銅の剣を購入できました。");
		} else {
			System.out.println("お金がないので購入できません。");
		}
		System.out.println("冒険に出かけました。");
	}
}
実行結果

金の剣を購入できました。
冒険に出かけました。

このサンプルの分岐処理は、最初にgold>=1000を実行し、偽が返されたので次のgold>=500を実行します。ここで真となったため中の金の剣購入の表示を実行し、そのままif ~ elseの塊の下まで処理が抜けます。
どれかの分岐が真になればそれ以降のelse if や else文は実行されないので注意しましょう。


さらにif文をネストさせて、複雑な条件を作り出すことができます。

複雑な条件となっても一つ一つ追っていけばわかるはずです。

public class Test{
	public static void main(String[] args){
		String charaName = "ヤン〇ス";
		//String charaName = "ゼ〇カ";
		//String charaName = "ク〇ール";
		int gold = 300;
		int power = 1;
		boolean whoIsThis = false;
		boolean isWoman = false;
		if ( "ヤン〇ス".equals(charaName) ) {
			if ( gold >= 1000 ) {
				System.out.println("白金の斧を購入できました。");
				power = 200;
			} else if ( gold >= 500 ) {
				System.out.println("金の斧を購入できました。");
				power = 100;
			} else if ( gold >= 300 ) {
				System.out.println("銀の斧を購入できました。");
				power = 50;
			} else if ( gold >= 100 ) {
				System.out.println("銅の斧を購入できました。");
				power = 20;
			} else {
				System.out.println("お金がないので購入できません。");
			}
		} else if ( "ゼ〇カ".equals(charaName) ) {
			if ( gold >= 1000 ) {
				System.out.println("白金のムチを購入できました。");
				power = 200;
			} else if ( gold >= 500 ) {
				System.out.println("金のムチを購入できました。");
				power = 100;
			} else if ( gold >= 300 ) {
				System.out.println("銀のムチを購入できました。");
				power = 50;
			} else if ( gold >= 100 ) {
				System.out.println("銅のムチを購入できました。");
				power = 20;
			} else {
				System.out.println("お金がないので購入できません。");
			}
			isWoman = true;
		} else if ( "ク〇ール".equals(charaName) ) {
			System.out.println("イケメンには何も売りません。");
		} else {
			whoIsThis = true;
		}
		if ( whoIsThis ) {
			System.out.println("あなたは冒険者ではありません。");
		} else {
			if ( isWoman && power < 100 ) { 
				System.out.println("か弱い女性には白金のムチを差し上げましょう。");
				power = 200; 
			}
			System.out.println(charaName+"は冒険に出かけました。");
			if ( power > 100 ) {
				System.out.println(charaName+"は魔王を倒しました。");
			} else {
				System.out.println(charaName+"は魔王にやられました。");
			}
		}
	}
}
実行結果

銀の斧を購入できました。
ヤン〇スは冒険に出かけました。
ヤン〇スは魔王にやられました。

このプログラムのcharaNameを別の名前にしたり、goldを変更すると、分岐の仕方が変わります。

試しに変更してみてください。

このプログラムの内容が理解できれば条件分岐に関してはOKでしょう。

実際にゲームを作るとなると、さらに複雑な処理を作ることになりますので、時間をかけてでも理解できるようになってください。

switch文

条件分岐の方法にswitch文というのも存在します。

switch(比較対象){
	case 対象と比較する値:
		break;
	default:
		break;
}

breakを忘れるとそのまま下の処理が実行されますのでご注意ください。

defaultはそれ以外の処理を実行できます。

switch文は使用できない型がありますので、その点も知っておいてください。int型やString型等で使用できます。

こちらもネストしたりと複雑な条件を作ることはできますが、if文がマスターできれば問題ないので、簡単なサンプルだけ見ておきましょう。

public class Test{
	public static void main(String[] args){
		int type = 1;
		switch(type){
		case 1:
			//typeが1だった時の処理
			System.out.println("私は聖属性魔法が得意です。");
			break;
		case 2:
			//typeが2だった時の処理
			System.out.println("私は闇属性魔法が得意です。");
			break;
		case 3:
			//typeが3だった時の処理
			System.out.println("私は気合いで何とかします。");
			break;
		default:
			System.out.println("あなたは誰ですか?");
			break;
		}
	}
}
実行結果

私は聖属性魔法が得意です。

breakを忘れたときの処理も見ておきましょう。

public class Test{
	public static void main(String[] args){
		int type = 1;
		switch(type){
		case 1:
			//typeが1だった時の処理
			System.out.println("私は聖属性魔法が得意です。");
		case 2:
			//typeが2だった時の処理
			System.out.println("私は闇属性魔法が得意です。");
			break;
		case 3:
			//typeが3だった時の処理
			System.out.println("私は気合いで何とかします。");
			break;
		default:
			System.out.println("あなたは誰ですか?");
			break;
		}
	}
}
実行結果

私は聖属性魔法が得意です。
私は闇属性魔法が得意です。

case 1の分岐処理が終了した後にそのままcase 2の処理まで実行されてしまっているのがわかると思います。


Java 14では新しくswitch文の記述方式が追加されました。

新しい記述形式であればbreakを忘れて想定外の処理が実行されるということを防げます。

また、「,」を使用し、or条件にすることができます。こちらは通常のswitch文でも利用可能です。

public class Test {
	public static void main(String[] args) {
		int type = 2;
		switch(type) {
			case 1 -> System.out.println("ルシファー");//1行だと{}なしでも書けます。
			case 2,3 -> {
				//複数条件でも利用可能
				System.out.println("サリエル");
			}
		};
	}
}
実行結果

サリエル

さらにswitch文でyieldを使用し、値の返却を実行することもできるようになりました。

public class Test {
	public static void main(String[] args) {
		int type = 1;
		String name = switch(type) {
		case 1:
			yield "ルシファー";
		case 2:
			yield "サリエル";
		default:
			yield "";
		};
		System.out.println(name);
	}
}
実行結果

ルシファー

値を返すほうも->を使用し、省略形式で記述できます。

public class Test {
	public static void main(String[] args) {
		int type = 2;
		String name = switch(type) {
			case 1 -> "ルシファー";
			case 2 -> {
				yield "サリエル";
			}
			default -> "";
		};
		System.out.println(name);
	}
}
実行結果

サリエル

3項演算子

3項演算子については説明せずに終わるつもりでしたが、私自身が結構使いたくなってしまう場面が多いのでさらっと紹介だけしておきます。

3項演算子とは値を変数に代入したりするときにif文なしで条件分岐し、代入したい場合などに利用できます。

これもネストが可能なのですが、一気に可読性が悪くなるのでお勧めしません。

分岐条件 ? 真の時の値 : 偽の時の値

と定義しましょう。

それでは利用するサンプルをご覧ください。

public class Test{
	public static void main(String[] args) throws InterruptedException{
		int num = 100;
		String text = num >= 100 ? "100以上" : "100未満";
		System.out.println(text);
	}
}

実行結果

100以上