8 パターン・マッチング
パターン・マッチングでは、オブジェクトに特定の構造があるかどうかをテストし、一致がある場合には、そのオブジェクトからデータを抽出します。これはJavaでも実行できることです。ただし、パターン・マッチングには新しい言語拡張が導入されており、より簡潔で強力なコードを使用してオブジェクトから条件付きでデータを抽出できます。
パターンは、値に対して実行できるテストを示します。パターンは文および式のオペランドとして出現し、テストする値を提供します。たとえば、次の式について考えてみます:
s instanceof Rectangle rパターンRectangle rは、instanceof式のオペランドです。引数sの型がパターンで指定したもの(Rectangle)かどうかをテストします。パターンがテストする引数をターゲットと呼ぶことがあります。
ノート:
前の例のように、instanceofの右側のオペランドがパターンの場合、instanceofはパターン一致演算子です。
instanceofの右側のオペランドが型の場合、instanceofは型比較演算子です。次の例では、instanceofを型比較演算子として使用します:
s instanceof Rectangleパターンは、ゼロ個以上のパターン変数を宣言できます。たとえば、パターンRectangle rはrを1つのみ宣言します。
パターンに対して値をテストするプロセスはパターン・マッチングと呼ばれます。値がパターンに正常に一致した場合、パターン変数はターゲットのデータで初期化されます。この例では、sがRectangleの場合、sはRectangleに変換され、rに割り当てられます。
パターンは、switch文または式のcaseラベルでも使用できます。たとえば:
public static double getArea(Shape s) throws IllegalArgumentException {
switch (s) {
case Rectangle r:
return r.length() * r.width();
case Circle c:
return c.radius() * c.radius() * Math.PI;
default:
throw new IllegalArgumentException("Unrecognized shape");
}
}型パターンは、型と1つのパターン変数で構成されます。この例では、Rectangle rが型パターンです。
レコード・パターンは、レコード型とレコード・パターン・リスト(空の場合あり)で構成されます。たとえば、次のレコード宣言と式について考えてみます:
record Point(double x, double y) {}
// ...
obj instanceof Point(double a, double b)レコード・パターンPoint(double x, double y)は、ターゲットobjがPoint(double, double)かどうかをテストします。Point(double, double)である場合、objからxおよびy値を直接抽出し、パターン変数aおよびbにそれぞれ割り当てます。