Java講座: 条件分岐(if文、switch文)
条件分岐とは、「もし〇〇ならば××する」という処理のことです。
Javaで条件分岐を扱う方法として、if文とswitch文があります。
if文
if文はその名の通り、「もし」が成立する場合のみ実行されるプログラムを実装するための構文です。
「もし〇〇ならば××する」をif文で実装するためには、以下の形式のプログラムを書けばOKです。
if (〇〇) {
××
}例えば、「もし x = 1 なら、『xは1です』と出力する」プログラムは以下のように書けます。
if (x == 1) {
System.out.println("xは1です");
}ここで==という記号が出てきました。これはJavaにおけるイコールの意味を持ちます。本来数学では等号は=ですが、Javaでは=を「代入」の意味ですでに使用してしまっているため仕方なく==を同値記号として使っているわけです。気持ち悪いですね。
==のように、右辺と左辺の値を比較するための演算子は他にもあります。
この演算子のことは関係演算子や比較演算子と呼びます。両辺の値を比較し、その結果をtrueかfalseで返す役割があります。
せっかくなのでまとめておきます。
関係演算子
| 演算子 | 意味 |
|---|---|
| == | 右辺と左辺が正しいならtrue |
| != | 右辺と左辺が正しくないならtrue |
| > | 左辺 > 右辺ならtrue |
| < | 左辺 < 右辺ならtrue |
| >= | 左辺 ≧ 右辺ならtrue |
| <= | 左辺 ≦ 右辺ならtrue |
実は!の真の意味は否定です。そのため、if (!(x >= 1))のように書くと、「もし、xが1以上じゃなかったら」、すなわち、「xが1未満だったら」という意味になります。ただし、!>みたいな書き方はできません。
今後!をこのように使う機会はわりとあったりなかったりします。なんとなく覚えておきましょう。
プログラム例
実際にif文がしっかり条件分岐の処理ができていることを確かめましょう。
サンプルコードを以下に示します。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("x = ");
int x = sc.nextInt();
System.out.println();
if (x % 2 == 0) {
System.out.println("xは偶数です。");
} else {
System.out.println("xは奇数です。");
}
}
}これはキーボードで打ち込まれた値が偶数か奇数かを判定するプログラムです。%という記号が何を意味しているのかも思い出せると良いですね。このように、if文の括弧の中には普通の足し算や引き算などの演算子も使うことができます。
elseという言葉が使われていることに気付いたでしょうか?これは「もし〇〇なら」の「〇〇」が成り立たなかった場合の処理を実行するための言葉です。elseが「それ以外」という意味ですので、そのままですね。
さらに、「もし〇〇ではなく、××なら」といったような条件分岐を実装するためにはelse ifという構文を使います。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("x = ");
int x = sc.nextInt();
System.out.println();
if (x % 3 == 0) {
System.out.println("xは3の倍数です。");
} else if (x % 3 == 1) {
System.out.println("xを3で割った余りは1です。");
} else {
System.out.println("xを3で割った余りは2です。");
}
}
}論理積・論理和
今まで解説してきたif文の書き方だけでは意外と不便です。
たとえば、「xが5より大きい、かつxが奇数のとき」といった条件分岐を考えたとき、どうすれば実装できるのでしょうか?
ぶっちゃけこんな感じで書けば実装するだけならできます。
if (x > 5) {
if (x % 2 != 0) {
//...
}
}しかし、これとても不便です。なぜなら、分岐したい条件が増えれば増えるほどたくさんif文を書かなければいけないからです。
こんなお悩みを解決してくれるのが論理積、論理和です。
論理積は「かつ」を意味し、Javaでは&&と書くことで実装できます。
論理和は「または」を意味し、Javaでは||と書くことで実装できます。
論理積を使うことで、「xが5より大きい、かつxが奇数のとき」といった条件分岐をこのように書くことができます。
if (x > 5 && x % 2 != 0) {
//...
}1行で書ける分スマートですね。
if文は今後めちゃくちゃ使うので慣れておきましょう。 https://atcoder.jp/contests/abc058/tasks/abc058_a
https://atcoder.jp/contests/abc204/tasks/abc204_a
https://atcoder.jp/contests/abc141/tasks/abc141_a
switch文
ぶっちゃけてしまうと、すべての条件分岐はif文のみで実装できます。「条件分岐を実装する」という目的を達成するためだけならswitch文は必要ありません。
しかし、以下のようなプログラムを見て皆さんはどう思うでしょうか?
String rank = "秀";
if (rank.equals("秀")) {
System.out.println("素晴らしいです。");
} else if (rank.equals("優")) {
System.out.println("良い成績です。");
} else if (rank.equals("良")) {
System.out.println("まずまずの成績です。");
} else if (rank.equals("可")) {
System.out.println("ギリギリでしたね。");
} else if (rank.equals("不可")) {
System.out.println("?");
} else {
System.out.println("???????????????");
}(rank.equals()は、文字列同士専用の==のようなものです。文字列が同じであるかどうかを判断するためにはこのメソッドを使ってください。)
このコード、何度もrank.equals()が使われていてとても冗長だし、なによりダサいです。
このようなケースでこそswitch文が役立ちます。switch文の構文は以下のとおりです。
switch(式) {
case 値1:
「式 = 値1」のときに実行する処理
break;
case 値2:
「式 = 値2」のときに実行する処理
break;
...
default:
すべての値に合致しないときに実行する処理
break;
}switch文を使ってさっきのクソダサコードを書き直すと以下のようになります。
String rank = "秀";
switch (rank) {
case "秀":
System.out.println("素晴らしいです。");
break;
case "優":
System.out.println("良い成績です。");
break;
case "良":
System.out.println("まずまずの成績です。");
break;
case "可":
System.out.println("ギリギリでしたね。");
break;
case "不可":
System.out.println("?");
break;
default:
System.out.println("???????????????");
break;
}各caseの最後には必ずbreakを書くようにしてください。
余談
条件式を書く場合の注意点
if文や、後で解説するfor文、while文では、条件式の記述が重要になってきます。
条件式を書く場合に注意しておきたいことをまとめておきます。
==と=を間違えない
言葉の通りです。=は代入を表すため、間違えるとエラーを吐かれてめんどくさい上に人間の直感に反するため見つけるのが大変です。条件式を書くときには注意するようにしましょう。
boolean型の変数を==で比較しない
if文の()の中身は必ずtrueかfalseです。そのため、そもそもtrueかfalseしかありえないboolean型の変数を==で比較するのは冗長だし、見にくいです。
たとえばflagという名前のboolean変数があったとして、if (flag == true)と書いてはいけません。if (flag)だけで十分です。
条件式からは否定を可能な限り取り除く
条件式に否定が多いと人間は頭がこんがらがります。「〇〇じゃなくて、かつ××でもなくて⋯」とか書かれていても、結局どの条件ならそれを満たせるのかわかりにくいです。わかりやすさのためにも、否定は少ないほうが良いです。
そこで使えるのが高校数学で習った「ド・モルガンの法則」です。細かい説明は省きますが、!A && !B ⇔ !(A || B)や!A || !B ⇔ !(A && B)が成り立つという法則です。
switch文はもっとかっこよく書ける
実は アロー演算子(->) という演算子を使うことで、さっきのクソダサコードをもっとかっこいいswitch文で書くことができます。
String rank = "秀";
System.out.println(switch (rank) {
case "秀" -> "素晴らしいです。";
case "優" -> "良い成績です。";
case "良" -> "まずまずの成績です。";
case "可" -> "ギリギリでしたね。";
case "不可" -> "?";
default -> "????????????";
});