Javaプログラミング入門

8. 条件分岐

最終更新:

javatutorial

- view
管理者のみ編集可

条件分岐とは

プログラムは、常に同じ動作をするだけでなく、その時々の状況に応じて適切な処理を行うことが求められます。
例えば、テストの点数によって「合格」か「不合格」かを判定したり、ログイン時に入力されたIDとパスワードが正しいかを確認したりする場面があります。
このように、ある条件を満たしているかどうかによって実行する処理を変える仕組み条件分岐といいます。

Javaでは、if文switch文を使って条件分岐を実装できます。

条件式

例えば、私たちの日常生活でも条件によって行動を決めることがたくさんあります。

「もし雨が降っていたら、傘を持っていく」

「もしテストの点数が80点以上なら、合格!」

「もし財布に1000円以上あったら、ランチを食べる」
プログラムでも、これと同じように条件が満たされたら〇〇するという仕組みを作ることができます。
このとき、条件が満たされたかどうかを判定するのが条件式です。

条件式の結果

条件式の判定結果はtrue(真)またはfalse(偽)のどちらかになります。
true(真)→ 条件が成立した(満たしている)場合
false(偽)→ 条件が成立しなかった(満たしていない)場合

条件式によって判定された結果はboolean型の変数に代入することもできます。

比較演算子

ある条件が成り立つかどうかを判定し、それによって動作を変える仕組みをプログラムで実現するには、比較演算子を使った条件式が必要になります。
比較演算子は、左右の2つの値を比較して真(true)または偽(false)を判定するための演算子です。
例えば、以下のような比較をすることができます。
演算子 意味 記述例
== aとbは等しい a == b
!= aとbは等しくない a != b
> aはbより大きい a > b
< aはbより小さい a < b
>= aはb以上 a >= b
<= aはb以下 a <= b
サンプル:RelationalOperator.java
  1. public class RelationalOperator {
  2. public static void main(String[] args) {
  3. int a = 10;
  4. int b = 10;
  5. boolean result = false;
  6. // aとbは等しいか確認
  7. result = a == b;
  8. System.out.println("a == b : " + result);
  9. // aとbは等しくないか確認
  10. result = a != b;
  11. System.out.println("a != b : " + result);
  12. // aはbより大きいか確認
  13. result = a > b;
  14. System.out.println("a > b : " + result);
  15. // aはbより小さいか確認
  16. result = a < b;
  17. System.out.println("a < b : " + result);
  18. // aはb以上か確認
  19. result = a >= b;
  20. System.out.println("a >= b : " + result);
  21. // aはb以下か確認
  22. result = a <= b;
  23. System.out.println("a <= b : " + result);
  24. }
  25. }
  26.  
実行結果
a == b : true
a != b : false
a > b : false
a < b : false
a >= b : true
a <= b : true

論理演算子

プログラムでは、条件が〇〇のときに処理を実行するという場面がよくあります。
ただし、2つ以上の条件を組み合わせたい ということもあります。
例えば

「80点以上かつ宿題を提出していれば合格」

「雨が降っているまたは天気予報が雨なら傘を持っていく」
このように、複数の条件を組み合わせるために使うのが論理演算子です。

主に以下の3つの演算子を使用することが多いです。
演算子 意味 記述例
&& aかつbの条件が満たされている a && b
|| aまたはbの条件が満たされている a || b
! aの条件は満たされていない !a
サンプル:LogicalOperator.java
  1. public class LogicalOperator {
  2. public static void main(String[] args) {
  3. boolean a = true;
  4. boolean b = false;
  5. boolean result = false;
  6. // aかつbの条件が満たされている
  7. result = a && b;
  8. System.out.println("a && b : " + result);
  9. // aまたはbの条件が満たされている
  10. result = a || b;
  11. System.out.println("a || b : " + result);
  12. // aの条件は満たされていない
  13. result = !a;
  14. System.out.println("!a : " + result);
  15. // bの条件は満たされていない
  16. result = !b;
  17. System.out.println("!b : " + result);
  18. }
  19. }
  20.  
a && b : false
a || b : true
!a : false
!b : true

if文

if文は、プログラムの実行中に特定の条件を満たした場合にのみ、決められた処理を実行するための仕組みです。

例えば、スマートフォンのロック解除を考えてみましょう。
正しいパスワードが入力された場合にのみロックが解除され、不正なパスワードなら解除されません。

このように、条件を判定し(例:パスワードが正しい)、その結果に応じて処理(例:ロックを解除するor解除しない)を分岐させるのがif文の役割です。
プログラムの中では、もし○○なら××をするという判断をするためにif文が使われます。

記述方法

if文の記述方法は
if (条件式) {
}
 
になります。
()の中に入る条件式は比較演算子や論理演算子を使用した式などになります。

例:もしテストの点数が60点以上なら「合格」という文字列を出力したい場合
サンプル:IfSample.java
  1. public class IfSample {
  2. public static void main(String[] args) {
  3. int score = 75; // テストの点数
  4. if (score >= 60) {
  5. System.out.println("合格");
  6. }
  7. }
  8. }
  9.  
出力結果
合格
score >= 60という条件式がtrueなら"合格"と表示され
score >= 60がfalseの場合は、何も表示されません。

スコープ

スコープとは、変数を使うことができる範囲のことです。
if文の{}(波かっこ)の中で作った変数は、その{}の中でしか使うことができません
サンプル:ScopeExample.java
  1. public class ScopeExample {
  2. public static void main(String[] args) {
  3. int x = 10; // これはどこでも使える
  4. if (x > 5) {
  5. int y = 20; // この y は {} の中だけで使える
  6. System.out.println("x: " + x); // OK
  7. System.out.println("y: " + y); // OK
  8. }
  9. System.out.println("x: " + x); // OK
  10. System.out.println("y: " + y); // エラー!y はもう使えない
  11. }
  12. }
  13.  
実行結果
エラー: シンボルを見つけられません
        System.out.println("y: " + y);  // エラー!y はもう使えない
                                   ^
  シンボル:   変数 y
  場所: クラス Main
エラー1

解説:
変数xはmainメソッドの中で最初に宣言されているので
mainメソッドの{}の中なら、どこでも使えます
つまり、if文の中でも、その後の System.out.println(x);でも変数xを使うことができます。
変数yはif文の{}の中で作られているのでif文の{}の中だけで使えます
if文の外では変数yは存在しないので、エラーになってしまいます。
このように、変数の使える範囲の事をスコープと言いますので覚えておくようにしてください。

if-else文

先ほどのif文は条件が満たされている場合のみ初期を行いましたが
条件が満たされていない時、処理を行う方法があります。
それがelse文というもので、if文と組み合わせて使用します。

先ほどのif文は、条件が満たされている場合にのみ処理を実行しました。
しかし、条件が満たされていない場合にも別の処理を行いたいことがあります。
そのときに使うのがelse文です。
else文はif文と組み合わせて使い、条件が満たされていない場合の処理を指定することができます。
サンプル:IfElseSample.java
  1. public class IfElseSample {
  2. public static void main(String[] args) {
  3. int score = 75; // テストの点数
  4. if (score >= 60) {
  5. System.out.println("合格");
  6. } else {
  7. System.out.println("不合格");
  8. }
  9. }
  10. }
  11.  
こちらのプログラムは
もしscoreに代入される値が60未満だった場合、条件がfalseになるので、
代わりにelseブロック内の処理が実行されます。

else if文

if文とelse文は、ある条件を満たしているかどうかをチェックし、その結果によって実行する内容を決める仕組みです。
しかし、if文だけでは1つの条件しか判断できません。
もしいくつかの条件を順番にチェックして、当てはまるものを探したいという場合には、else if文を使います。
else if文とは、最初の条件に当てはまらなかった場合に、次の条件をチェックするための方法です。
こうすることで、いくつかの条件の中から一番合うものを選び、適切な処理を実行することができます。

else if文の基本的な文法

  1. if (条件1) {
  2. // 条件1がtrueのときに実行される処理
  3. } else if (条件2) {
  4. // 条件1がfalseで、条件2がtrueのときに実行される処理
  5. } else if (条件3) {
  6. // 条件1と条件2がfalseで、条件3がtrueのときに実行される処理
  7. } else {
  8. // すべての条件がfalseのときに実行される処理
  9. }
  10.  
💡ポイント
1. if は最初に条件をチェックする。
2. else if は、前の条件がfalseの場合に次の条件をチェックする。
3. else は、それまでのすべての条件がfalseだった場合に実行される(省略可能)。
4. 上から順番に判定され、最初にtrueになった部分の処理が実行される。
5. それ以降の条件はチェックされない。
サンプル:ElseIfSample.java
  1. public class ElseIfSample {
  2. public static void main(String[] args) {
  3. int score = 85; // 例:テストの点数
  4. if (score >= 90) {
  5. System.out.println("成績はAです");
  6. } else if (score >= 80) {
  7. System.out.println("成績はBです");
  8. } else if (score >= 70) {
  9. System.out.println("成績はCです");
  10. } else if (score >= 60) {
  11. System.out.println("成績はDです");
  12. } else {
  13. System.out.println("成績はEです");
  14. }
  15. }
  16. }
  17.  
実行結果
成績はBです
このプログラムの動き
score が 90 以上 → 「成績はAです」を表示
score が 80 以上 90 未満 → 「成績はBです」を表示
(この例では 85 なので、ここで処理が決定)
score が 70 以上 80 未満 → 「成績はCです」を表示
score が 60 以上 70 未満 → 「成績はDです」を表示
score が 60 未満 → 「成績はF(不合格)です」を表示

else if文を使用する際は、条件式を判定する順番に気を付ける必要があります。
先ほどの条件を成績Aと成績Cの条件を逆にしてみましょう。
  1. public class Main {
  2. public static void main(String[] args) {
  3. int score = 85; // 例:テストの点数
  4. if (score >= 70) {
  5. System.out.println("成績はCです");
  6. } else if (score >= 80) {
  7. System.out.println("成績はBです");
  8. } else if (score >= 90) {
  9. System.out.println("成績はAです");
  10. } else if (score >= 60) {
  11. System.out.println("成績はDです");
  12. } else {
  13. System.out.println("成績はEです");
  14. }
  15. }
  16. }
  17.  
実行結果
成績はCです
変数scoreに代入している値は85なのにもかかわらず、成績がAになりませんでした。
先ほどのポイントにもありましたが、if文に記載している条件式は上から順番に判定され、最初にtrueになった部分の処理が実行されます。

そのため、このように条件式の順番を間違えてしまうと、思わぬバグを生んでしまう可能性がありますので注意が必要です。

文字列の比較

Javaで文字列を比べるときは==で、正しく比較することができません。
サンプル:StringComparison.java
  1. public class Main {
  2. public static void main(String[] args) {
  3. String str1 = "Hello";
  4. String str2 = "H";
  5. str2 += "e";
  6. str2 += "l";
  7. str2 += "l";
  8. str2 += "o";
  9. System.out.println("str1 : " + str1);
  10. System.out.println("str2 : " + str2);
  11. System.out.println("str1 == str2 : " + (str1 == str2));
  12. }
  13. }
  14.  
実行結果
str1 : Hello
str2 : Hello
str1 == str2 : false
==ではなく(文字列を代入した)変数名.equals()という命令を使うのが正解です。
.equals()の()の中比較したい文字列を指定します。
サンプル:EqualsSample.java
public class EqualsSample {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "H";
        str2 += "e";
        str2 += "l";
        str2 += "l";
        str2 += "o";
        System.out.println("str1 : " + str1);
        System.out.println("str2 : " + str2);
        System.out.println("str1.equals(str2) : " + str1.equals(str2));
    }
}
 
実行結果
str1 : Hello
str2 : Hello
str1.equals(str2) : true
現時点では、文字列の比較は==ではなく(文字列を代入した)変数名.equals()という命令を使うという事だけを理解していただければ問題ありません。
それでも、何故このような現象が起きるのかが気になる方は、下のコラムを参照してください。

switch文


みなさん、自動販売機で飲み物を買ったことあると思います。
自動販売機は、お金を入れてボタンを押すと、選んだ飲み物が出てくる仕組みです。
例えば、コーラのボタンを押したらコーラが出る、お茶のボタンを押したらお茶が出るのように、それぞれのボタンに決まった飲み物が対応しています。
プログラミングでも、こういう選んだものに応じて処理を変えることができます。
それがswitch文になります。
たとえば、番号を入力して「1番ならコーラ」「2番ならお茶」「3番なら水」と表示するようなプログラムを作ることができます。
もちろんif文を使用しても、同じ処理を書くことができますが、何回もif文を書かないといけなくて大変です。
サンプル:DrinkSelectUseIf.java
  1. public class DrinkSelectUseIf {
  2. public static void main(String[] args) {
  3. // 選択した番号
  4. int choice = 2;
  5. if (choice == 1) {
  6. System.out.println("コーラです!");
  7. } else if (choice == 2) {
  8. System.out.println("お茶です!");
  9. } else if (choice == 3) {
  10. System.out.println("水です!");
  11. } else if (choice == 4) {
  12. System.out.println("ジュースです!");
  13. } else {
  14. System.out.println("その番号の飲み物はありません!");
  15. }
  16. }
  17. }
  18.  
こうなると、選択肢が増えるたびにelse ifをどんどん書き足さなければならず、見た目も読みにくくなります。
このように、判定する値の種類(選択肢)が増えるほど、if文よりもswitch文の方がコードが読みやすくなり、管理もしやすくなります。

記述方法

switch文の記述方法は
switch (判定する値) {
    case1:
        // 値1に一致したときの処理
        break;
    case2:
        // 値2に一致したときの処理
        break;
    case3:
        // 値3に一致したときの処理
        break;
    default:
        // どの値にも一致しないときの処理
}
 
になります。
()の中に入る値は、今まで習ったデータ型だと、byte型、short型、int型、char型、String型のみが指定できます。
float型、double型、long型、boolean型は指定することができません。

例:先ほどのif文で書いた自動販売機のプログラムをswitch文で記載した場合
サンプル:DrinkSelectUseSwitch.java
  1. public class DrinkSelectUseSwitch {
  2. public static void main(String[] args) {
  3. int choice = 2;
  4. switch (choice) {
  5. case 1:
  6. System.out.println("コーラです!");
  7. break;
  8. case 2:
  9. System.out.println("お茶です!");
  10. break;
  11. case 3:
  12. System.out.println("水です!");
  13. break;
  14. case 4:
  15. System.out.println("ジュースです!");
  16. break;
  17. default:
  18. System.out.println("その番号の飲み物はありません!");
  19. }
  20. }
  21. }
  22.  
実行結果
お茶です!

例:判定する値を文字列にした場合
サンプル:DrinkSelectUseSwitchString.java
  1. public class DrinkSelectUseSwitchString {
  2. public static void main(String[] args) {
  3. String drink = "コーラ";
  4. switch (drink) {
  5. case "コーラ":
  6. System.out.println("コーラが出ます!");
  7. break;
  8. case "お茶":
  9. System.out.println("お茶が出ます!");
  10. break;
  11. case "水":
  12. System.out.println("水が出ます!");
  13. break;
  14. default:
  15. System.out.println("その飲み物はありません。");
  16. }
  17. }
  18. }
  19.  
実行結果
コーラが出ます!

case文

switch文は、何かの値によってやることを決めるときに使います。
その中でもcaseはもしこの値だったら、この処理をするよ!と決める部分になります。

break;は何のためにあるの?

試しにbreakを全て抜いたやつを実行してみましょう。
サンプル:DrinkSelectNoUseBreak.java
  1. public class DrinkSelectNoUseBreak {
  2. public static void main(String[] args) {
  3. String drink = "コーラ";
  4. switch (drink) {
  5. case "コーラ":
  6. System.out.println("コーラが出ます!");
  7. case "お茶":
  8. System.out.println("お茶が出ます!");
  9. case "水":
  10. System.out.println("水が出ます!");
  11. default:
  12. System.out.println("その飲み物はありません。");
  13. }
  14. }
  15. }
  16.  
実行結果
  1. コーラが出ます!
  2. お茶が出ます!
  3. 水が出ます!
  4. その飲み物はありません。
このままだと、すべての飲み物が表示されてしまいます。
そのため、それぞれのcaseで処理を止めたい場合は、breakを忘れずに書きましょう

💡注意
switch文の比較はあくまで ==です。
大小の比較は行うことができませんので注意が必要です。

コラム

もう一つの論理演算子

3つの論理演算子を紹介しましたが、実はあと1つだけあります。
あまり一般的に使いませんが、知っておいて損はありません。
演算子 説明 記述例
^ aまたはbの条件が満たされている a ^ b
||は、どちらか一方または両方が条件を満たせば良いですが
^は、どちらか一方の条件を満たしている時でないといけません。
また、&&を論理積、||を論理和、!を否定、^を排他的論理和と呼んでいます。

スコープは自作できます

{}(ブロック)は、単体で使うことができます。
必ずしもif文やswitch文などの構文と一緒に書く必要はありません。
そのため、以下のように ブロックのスコープを利用すると、同じ変数名を別々のブロックで定義することが可能です。
(ただし、この書き方は非常に危険ですので全く推奨されません)
  1. public class Main {
  2. public static void main(String[] args) {
  3. {
  4. int a = 10;
  5. System.out.println(a);
  6. }
  7. {
  8. int a = 20;
  9. System.out.println(a);
  10. }
  11. }
  12. }
  13.  

なんで文字列は==で比較をしてはいけないの?

==演算子は、数値同士を比較するための演算子です。
また、char型やboolean型も内部的には数値として扱われます。
文字列同士を==で比較すると、文字列の中身ではなく、メモリ上の参照先を比べることになります。
文字列が作られると、コンピュータのメモリのどこかにその文字列が保存されます。
そして、変数には文字列の中身ではなく、その保存場所(メモリのアドレスのような値)が入る仕組みになっています。

そのため、== で比較すると、文字列そのものが同じか?ではなく、同じ場所を指しているか?を比べている ことになります。

equals()を使用すると、文字列全体を比較する処理が動き、文字列そのものが同じかを判定してくれます。

switch文のdefaultって省略できないの?

  • switch文のdefaultが省略できる場合
すべてのケースを網羅できる場合、defaultを書かなくても問題ありません。
ただし、これができるのは、大体switch文の条件に列挙型の変数を使っている場合のみです。
それ以外のデータ型では、基本的にすべてのケースを網羅するのは難しいため、defaultを書くのが一般的です。
例えば、byte型は理論的にはすべてのケースを網羅でそうですが、int型やString型などは現実的に網羅しきれません。
そのため、defaultを省略したい場合は、網羅性を考慮して列挙型を使うのがおすすめです。
  • switch文のdefaultが省略できない場合
すべてのケースを網羅できない場合は、適切な処理を行うためにdefaultを書く必要があります。
例えば、列挙型をswitch文で使うとき、すべての列挙型定数をcaseに書ききれない場合があります。
このように、予想外の値が渡ってくる可能性がある場合は、適切な処理を行うためにdefaultを用意しておくべきです。
また、エラー処理のためにもdefaultが必要です。
どの case にも当てはまらないときに、例外を発生させる、エラーメッセージをログに記録する
といった処理を行いたい場合、defaultを使うのが一般的です。

人気記事ランキング
ウィキ募集バナー