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
にそれぞれ割り当てます。