Pattern Matching for Switch in Java 17

Introduction

In this article, we will learn about a very important Java 17 feature pattern matching for switch statements. Java 17 introduced an exciting feature called pattern matching for switch statements and expressions. This enhancement builds upon the pattern-matching capabilities introduced in earlier versions, making switch constructs more powerful and expressive.

What is Pattern Matching for Switch?

Pattern matching for a switch allows you to test whether an object matches a certain pattern or extract information from it in a single step. This feature enables more short and readable code, especially when dealing with complex data structures.

Basic Syntax

The basic syntax for pattern matching in switch looks like the below example.

switch (obj) {
    case Pattern1 matchedVariable1 -> // example code
    case Pattern2 matchedVariable2 -> // example code
    default -> // example code
}

Let's dive deep into some examples to see how pattern matching for switches works in practice.

1. Type Patterns

public static String getObjectType(Object obj) {
    return switch (obj) {
        case Integer i -> "It's an Integer: " + i;
        case String s -> "It's a String: " + s;
        case Double d -> "It's a Double: " + d;
        case null -> "It's null";
        default -> "It's something else";
    };
}

public static void main(String[] args) {
    System.out.println(getObjectType(42));
    System.out.println(getObjectType("Hello"));
    System.out.println(getObjectType(3.14));
    System.out.println(getObjectType(null));
    System.out.println(getObjectType(new ArrayList<>()));
}

Output

It's an Integer: 42
It's a String: Hello
It's a Double: 3.14
It's null
It's something else

Project

In the above example, we use type patterns to match against different types of objects. The switch statement automatically casts the object to the matched type, allowing us to use it directly in the case block.

2. Conditional expressions

Java 17 also allows you to use conditional expressions with pattern matching.

public static String categorizeNumber(Object obj) {
    return switch (obj) {
        case Integer i when i < 0 -> "Negative integer";
        case Integer i when i > 0 -> "Positive integer";
        case Integer i -> "Zero";
        case Double d when d < 0 -> "Negative double";
        case Double d when d > 0 -> "Positive double";
        case Double d -> "Zero double";
        default -> "Not a number";
    };
}

public static void main(String[] args) {
    System.out.println(categorizeNumber(-5));
    System.out.println(categorizeNumber(0));
    System.out.println(categorizeNumber(3.14));
    System.out.println(categorizeNumber("42"));
}

Output

Negative integer
Zero
Positive double
Not a number

This example demonstrates how we can use guarded patterns to add additional conditions to our cases.

Output

Summary

Pattern matching for switches in Java 17 is a powerful feature that enhances code readability and expressiveness. It's particularly useful when working with complex object hierarchies, sealed classes, and records. By combining type patterns, guarded patterns, and record patterns, you can write more concise and maintainable code.