The art of pattern matching in java

Pattern matching involves testing whether an object has a particular structure, then extracting data from that object if there’s a match.

if (shape instanceof Rectanble rectangle && rectangle.length() > 4) {
  // ...
}
 
// unamed pattern
if (object instanceof Point(var x, _)) {
  // ...
}
 
return switch(shape) {
  case Rectangle s -> 2 * s.lenght() + 2 * s.width();
  case Circle s -> 2 * s.radius() * Math.PI;
  default -> throw new IllegalArgumentException();
}
 
return switch(shape) {
  case Rectangle r when r.length() > 8 -> 3 * s.lenght() + 3 * s.width();
  case Rectangle r -> 2 * r.lenght() + 2 * r.width();
  case Circle c -> 2 * c.radius() * Math.PI;
  case null, default -> throw new IllegalArgumentException();
}
 
// switch - pattern label dominance
switch(object) {
  // /!\ be careful with the order of the pattern labels!
  case CharSequence cs -> System.out.println("A sequence of length " + cs.length());
  case String s -> System.out.println("A String " + s);
  default -> {}
}

Abstract

Guarded patterns (JDK 19):

void shapeTester(Shape shape) {
  switch (shape) {
    // only works for patterns, no case "Foo" when somethingElse() -> ...
    case Triangle t when t.area() > 25 -> System.out.println("It's a big triangle");
    case Triangle t -> System.out.println("It's a small triangle");
    case Square s -> System.out.println("It's a small square");
    case Pentagon t -> System.out.println("It's a small pentagon");
    case Shape t -> System.out.println("It's a small shape");
  }
}

Patterns will be composable

public void printColor(Rectangle r) {
  if (r instanceof ColourRectangle(ColourPoint(Point p, Colour c), ColourPoint br)) {
    System.out.println(c);
  }
}