Java/基礎/条件分岐
< Java
条件分岐
編集概要
編集条件分岐は、プログラムの実行フローを制御する基本的な構造の1つです。この章では、Javaにおける以下の条件分岐の仕組みを解説します:
- if-else文による基本的な条件分岐
- switch文による複数条件の分岐
- switch式による値を返す条件分岐
- 論理演算子を使用した条件の組み合わせ
- 三項演算子による簡潔な条件分岐
- パターンマッチングによる型に基づく分岐
基本的な条件分岐:if-else文
編集構文
編集if-else文の基本構文は以下の通りです:
if (条件式) { // 条件が真の場合の処理 } else { // 条件が偽の場合の処理 }
複数条件の判定
編集複数の条件を判定する場合は、else if を使用します:
if (条件式1) { // 条件1が真の場合の処理 } else if (条件式2) { // 条件2が真の場合の処理 } else { // いずれの条件も偽の場合の処理 }
実践例
編集public class IfElseExample { public static void main(String[] args) { var n = 0.0 / 0.0; if (n < 0.0) { System.out.println("負の数です"); } else if (n > 0.0) { System.out.println("正の数です。"); } else if (n == 0.0) { System.out.println("零です。"); } else { System.out.println(n + "です。"); } } }
複数条件の分岐:switch文
編集基本構文
編集switch文は、1つの値に基づいて複数の分岐を行う場合に使用します:
switch (式) { case 値1: // 値1の場合の処理 break; case 値2: // 値2の場合の処理 break; default: // どの値にも一致しない場合の処理 break; }
文字列による分岐例
編集String fruit = "りんご"; switch (fruit) { case "りんご": case "バナナ": case "いちご": System.out.println(fruit + "は果物です"); break; default: System.out.println(fruit + "は果物ではありません"); break; }
enum型による分岐例
編集enum Animal { DOG, CAT, BIRD } Animal pet = Animal.DOG; switch (pet) { case DOG: System.out.println("ワンワン"); break; case CAT: System.out.println("ニャー"); break; case BIRD: System.out.println("ピヨピヨ"); break; }
値を返す条件分岐:switch式
編集基本構文
編集Java 12以降で導入されたswitch式は、条件分岐の結果を値として返すことができます:
var result = switch (式) { case 値1 -> 返り値1; case 値2 -> 返り値2; default -> デフォルト値; };
実践例
編集String fruit = "りんご"; int score = switch (fruit) { case "りんご", "バナナ", "いちご" -> 1; case "メロン", "スイカ" -> 2; default -> 0; };
条件の組み合わせ:論理演算子
編集主な論理演算子
編集演算子 意味 例 && 論理積(AND) A && B
|| 論理和(OR) A || B
! 論理否定(NOT) !A
== 等価 A == B
!= 不等価 A != B
真理値表
編集論理演算子の真理値表 A B !A A && B A || B false false true false false false true true false true true false false false true true true false true true
この表では、AとBがそれぞれ真(true)または偽(false)の場合に対する、NOT、AND、ORの結果が示されています。
簡潔な条件分岐:三項演算子
編集構文
編集結果 = 条件式 ? 真の場合の値 : 偽の場合の値;
実践例
編集int a = 5, b = 10; int max = a > b ? a : b; // より大きい値を選択
パターンマッチングによる型判定
編集instanceofによるパターンマッチング
編集Java 16以降で導入された新しい構文:
if (obj instanceof String str) { System.out.println(str.toUpperCase()); }
switchでのパターンマッチング
編集Java 21以降で導入された新機能:
String formatted = switch (obj) { case Integer i -> "整数: " + i; case String s -> "文字列: " + s; case null -> "null値"; default -> "その他: " + obj; };
パターンマッチングのキャプチャー
編集キャプチャーとは
編集パターンマッチングにおけるキャプチャーとは、マッチしたパターンの値を変数に代入して再利用できるようにする機能です。これにより、型チェックとキャストを1つの操作で安全に行うことができます。
キャプチャー変数のスコープ
編集キャプチャー変数は、パターンマッチングが成功した場合にのみ使用可能です:
if (obj instanceof String s && s.length() > 0) { // このスコープでsを使用可能 System.out.println(s.toUpperCase()); } // このスコープではsは使用不可
ガード条件でのキャプチャー
編集キャプチャー変数は、パターンマッチングのガード条件内でも使用できます:
public record Point(int x, int y) {} void processPoint(Object obj) { if (obj instanceof Point p && p.x() > 0 && p.y() > 0) { // 正の座標の場合の処理 System.out.println("正の座標: " + p); } }
switch式でのキャプチャー
編集switch式でもキャプチャーを使用できます:
String describe(Object obj) { return switch (obj) { case String s when s.length() > 0 -> "非空の文字列: " + s; case String s -> "空の文字列"; case Integer i when i > 0 -> "正の整数: " + i; case Integer i -> "0または負の整数: " + i; case null -> "null値"; default -> obj.toString(); }; }
ネストされたパターンでのキャプチャー
編集複雑なデータ構造でもパターンマッチングとキャプチャーを組み合わせることができます:
record Person(String name, Address address) {} record Address(String street, String city) {} void processPerson(Object obj) { if (obj instanceof Person p && p.address() instanceof Address a && a.city().equals("東京")) { // 東京在住の人の処理 System.out.println(p.name() + "さんは東京在住です"); } }
キャプチャーの利点
編集利点 説明 型安全性 コンパイル時の型チェックにより、型関連のエラーを防ぐ コードの簡潔さ 型チェックとキャストを1行で行える 可読性 意図が明確で理解しやすいコードになる スコープの制限 変数の使用範囲が適切に制限される
キャプチーにおける注意点
編集- キャプチャー変数は、パターンマッチングが成功した場合にのみ初期化される
- 同じスコープ内で既存の変数名と競合してはいけない
- switch式では、各caseブランチで異なるキャプチャー変数を使用できる
- ガード条件(when節)内でもキャプチャー変数を使用可能
パターンマッチングとキャプチャーの組み合わせ例
編集sealed interface Shape permits Circle, Rectangle { double area(); } record Circle(double radius) implements Shape { public double area() { return Math.PI * radius * radius; } } record Rectangle(double width, double height) implements Shape { public double area() { return width * height; } } String describeShape(Shape shape) { return switch (shape) { case Circle c when c.radius() > 10 -> "大きな円(半径: " + c.radius() + ")"; case Circle c -> "円(半径: " + c.radius() + ")"; case Rectangle r when r.width() == r.height() -> "正方形(辺長: " + r.width() + ")"; case Rectangle r -> "長方形(幅: " + r.width() + ", 高さ: " + r.height() + ")"; }; }
補足
編集パターンマッチングの種類
編集パターン 説明 例 型パターン 型の一致を確認 case String s nullパターン null値の確認 case null リテラルパターン 具体的な値との一致 case 42 列挙型パターン 列挙型の値との一致 case Color.RED デコンストラクタパターン オブジェクトの構造分解 case Point(int x, int y)