10 Unnamed Variables and Patterns
                  Unnamed variables are variables that can be initialized but not used. Unnamed
            patterns can appear in a pattern list of a record pattern, and always match the
        corresponding record component. You can use them instead of a type pattern. They remove the
        burden of having to write a type and name of a pattern variable that's not needed in
        subsequent code. You denote both with the underscore character
        (_).
               
For background information about unnamed variables and patterns, see JEP 456.
Unnamed Variables
You can use the underscore keyword (_) as the name of a
                local variable, exception, or lambda parameter in a declaration when the value of
                the declaration isn't needed. This is called an unnamed variable, which
                represents a variable that’s being declared but it has no usable name.
                  
Unnamed variables are useful when the side effect of a statement is more important than its result.
Consider the following example that iterates through the elements of the
                array orderIDs with a for loop. The side effect of
                this for loop is that it calculates the number of elements in
                    orderIDs without ever using the loop variable
                    id:
                  
        int[] orderIDs = {34, 45, 23, 27, 15};
        int total = 0;
        for (int id : orderIDs) {
            total++;
        }
        System.out.println("Total: " + total);You can use an unnamed variable to omit or elide the unused
                variable id:
                  
        int[] orderIDs = {34, 45, 23, 27, 15};
        int total = 0;
        for (int _ : orderIDs) {
            total++;
        }
        System.out.println("Total: " + total);The following table describes where you can declare an unnamed variable:
Table 10-1 Valid Unnamed Variable Declarations
| Declaration Type | Example with Unnamed Variable | 
|---|---|
| A local variable declaration statement in a block | Note that you don't have to assign the value returned by Queue::remove to a variable, named or unnamed. You might want to do so to signify that a lesser-known API returns a value that your application doesn't use. | 
| A resource specification of a try-with-resources statement |  | 
| The header of a basic forstatement |  | 
| The header of an enhanced forloop |  | 
| An exception parameter of a catchblock |  | 
| A formal parameter of a lambda expression |  | 
Unnamed Patterns
Consider the following example that calculates the distance between two
                instances of ColoredPoint:
                  
    record Point(double x, double y) {}
    enum Color { RED, GREEN, BLUE }
    record ColoredPoint(Point p, Color c) {}
    double getDistance(Object obj1, Object obj2) {
        if (obj1 instanceof ColoredPoint(Point p1, Color c1) &&
            obj2 instanceof ColoredPoint(Point p2, Color c2)) {
        return java.lang.Math.sqrt(
            java.lang.Math.pow(p2.x - p1.x, 2) +
            java.lang.Math.pow(p2.y - p1.y, 2));
        } else {
            return -1;
        }
    }The example doesn't use the Color component of the
                    ColoredPoint record. To simplify the code and improve
                readability, you can elide the type patterns Color c1 and
                    Color c2 with the unnamed pattern (_):
                  
    double getDistance(Object obj1, Object obj2) {
        if (obj1 instanceof ColoredPoint(Point p1, _) &&
            obj2 instanceof ColoredPoint(Point p2, _)) {
        return java.lang.Math.sqrt(
            java.lang.Math.pow(p2.x - p1.x, 2) +
            java.lang.Math.pow(p2.y - p1.y, 2));
        } else {
            return -1;
        }
    }Alternatively, you can keep the type pattern's type and elide just its name:
        if (obj1 instanceof ColoredPoint(Point p1, Color _) &&
            obj2 instanceof ColoredPoint(Point p2, Color _))No value is bound to the unnamed pattern variable. Consequently, the highlighted statement in the following example is invalid:
        if (obj1 instanceof ColoredPoint(Point p1, Color _) &&
            obj2 instanceof ColoredPoint(Point p2, Color _)) {
            // Compiler error: the underscore keyword '_" is only allowed to
            // declare unnamed patterns, local variables, exception parameters or
            // lambda parameters
            System.out.println("Color: " + _); 
            // ...
        }   Also, you can't use an unnamed pattern as a top-level pattern:
        // Compiler error: the underscore keyword '_' is only allowed to
        // declare unnamed patterns, local variables, exception parameters or
        // lambda parameters        
        if (obj1 instanceof _) {
            // ...
        }You can use unnamed patterns in switch expressions and
                statements: 
                  
    sealed interface Employee permits Salaried, Freelancer, Intern { }
    record Salaried(String name, long salary) implements Employee { }
    record Freelancer(String name) implements Employee { }
    record Intern(String name) implements Employee { }
        
    void printSalary(Employee b) {
        switch (b) {
            case Salaried r   -> System.out.println("Salary: " + r.salary());
            case Freelancer _ -> System.out.println("Other");
            case Intern _     -> System.out.println("Other");
        }
    }You may use multiple patterns in a case label provided
                that they don't declare any pattern variables. For example, you can rewrite the
                previous switch statement as follows:
                  
        switch (b) {
            case Salaried r              -> System.out.println("Salary: " + r.salary());
            case Freelancer _, Intern _  -> System.out.println("Other");
        }