Java12 Switch表达式案例

wen java案例 2

Java 12 Switch 表达式详解

Java 12 引入了 Switch 表达式作为预览特性,这是对传统 Switch 语句的重大改进,以下是详细案例:

Java12 Switch表达式案例

传统 Switch vs Switch 表达式

传统 Switch 语句(Java 8 及之前)

// 传统写法:容易出现穿透问题,代码冗长
public static String getDayType(int day) {
    String type;
    switch (day) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            type = "工作日";
            break;
        case 6:
        case 7:
            type = "周末";
            break;
        default:
            type = "无效日期";
            break;
    }
    return type;
}

Java 12 Switch 表达式

// 新写法:简洁、无穿透、有返回值
public static String getDayType(int day) {
    return switch (day) {
        case 1, 2, 3, 4, 5 -> "工作日";
        case 6, 7 -> "周末";
        default -> "无效日期";
    };
}

箭头语法(Arrow Syntax)

基本用法

public class SwitchExpressionDemo {
    public static void main(String[] args) {
        // 示例1:季节判断
        String season = getSeason(3);
        System.out.println("3月是: " + season);  // 输出:3月是: 春季
        // 示例2:数值计算
        int result = calculate(10, 5, '+');
        System.out.println("10 + 5 = " + result);  // 输出:10 + 5 = 15
    }
    // 季节判断
    static String getSeason(int month) {
        return switch (month) {
            case 12, 1, 2 -> "冬季";
            case 3, 4, 5 -> "春季";
            case 6, 7, 8 -> "夏季";
            case 9, 10, 11 -> "秋季";
            default -> "无效月份";
        };
    }
    // 简单计算器
    static int calculate(int a, int b, char operator) {
        return switch (operator) {
            case '+' -> a + b;
            case '-' -> a - b;
            case '*' -> a * b;
            case '/' -> a / b;
            default -> throw new IllegalArgumentException("无效运算符: " + operator);
        };
    }
}

多值匹配

public class MultiValueMatch {
    public static void main(String[] args) {
        System.out.println(getFruitColor("apple"));   // 红色
        System.out.println(getFruitColor("banana"));  // 黄色
        System.out.println(getFruitColor("grape"));   // 紫色
    }
    static String getFruitColor(String fruit) {
        return switch (fruit.toLowerCase()) {
            case "apple", "strawberry", "cherry" -> "红色";
            case "banana", "lemon", "mango" -> "黄色";
            case "grape", "plum", "berry" -> "紫色";
            case "orange", "peach" -> "橙色";
            default -> "未知颜色";
        };
    }
}

块级表达式(使用 yield)

当需要执行多条语句时,使用 yield 返回值:

public class BlockExpression {
    public static void main(String[] args) {
        System.out.println(evaluateGrade(85));
        System.out.println(evaluateGrade(72));
        System.out.println(evaluateGrade(45));
    }
    static String evaluateGrade(int score) {
        return switch (score / 10) {
            case 10, 9 -> {
                if (score >= 95) {
                    yield "优秀 (A+)";
                } else {
                    yield "优秀 (A)";
                }
            }
            case 8 -> {
                String grade = "良好 (B)";
                if (score >= 85) {
                    grade = "良好 (B+)";
                }
                yield grade;
            }
            case 7 -> "中等 (C)";
            case 6 -> "及格 (D)";
            default -> {
                if (score >= 0) {
                    yield "不及格 (F)";
                } else {
                    yield "无效分数";
                }
            }
        };
    }
}

枚举类型使用

enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumSwitch {
    public static void main(String[] args) {
        Day day = Day.SATURDAY;
        System.out.println(isWeekend(day));  // true
        System.out.println(getDayActivity(day));  // 享受周末时光
        // 遍历所有枚举值
        for (Day d : Day.values()) {
            System.out.printf("%-10s: %s%n", d, getDayActivity(d));
        }
    }
    static boolean isWeekend(Day day) {
        return switch (day) {
            case SATURDAY, SUNDAY -> true;
            default -> false;
        };
    }
    static String getDayActivity(Day day) {
        return switch (day) {
            case MONDAY -> "开始工作";
            case TUESDAY, WEDNESDAY, THURSDAY -> "正常工作";
            case FRIDAY -> "准备周末";
            case SATURDAY -> "享受周末时光";
            case SUNDAY -> "准备新的一周";
        };
    }
}

复杂业务逻辑

public class BusinessLogic {
    public static void main(String[] args) {
        // 订单状态处理
        Order order1 = new Order("ORD001", 500, OrderStatus.PENDING);
        System.out.println(processOrder(order1));
        // 支付方式处理
        String paymentResult = handlePayment("crypto", 1000);
        System.out.println(paymentResult);
    }
    enum OrderStatus {
        PENDING, CONFIRMED, SHIPPED, COMPLETED, CANCELLED
    }
    static class Order {
        String id;
        double amount;
        OrderStatus status;
        Order(String id, double amount, OrderStatus status) {
            this.id = id;
            this.amount = amount;
            this.status = status;
        }
    }
    static String processOrder(Order order) {
        return switch (order.status) {
            case PENDING -> {
                double discount = order.amount > 500 ? 0.1 : 0.05;
                yield String.format("订单 %s 待处理,可享受 %.0f%% 折扣", order.id, discount * 100);
            }
            case CONFIRMED -> "订单已确认,准备发货";
            case SHIPPED -> "订单已发货,请等待收货";
            case COMPLETED -> "订单已完成,感谢购买";
            case CANCELLED -> "订单已取消";
        };
    }
    // 多种支付方式处理
    static String handlePayment(String method, double amount) {
        return switch (method) {
            case "alipay" -> "使用支付宝支付 " + amount + " 元";
            case "wechat" -> "使用微信支付 " + amount + " 元";
            case "credit" -> {
                yield amount > 5000 ? "信用额度超限" : "使用信用卡支付 " + amount + " 元";
            }
            case "crypto" -> "使用加密货币支付 " + amount + " 元";
            default -> "不支持的支付方式";
        };
    }
}

类型转换(使用模式匹配,Java 17+)

public class PatternMatchingDemo {
    public static void main(String[] args) {
        Object obj1 = "Hello Java 12";
        Object obj2 = 42;
        Object obj3 = 3.14;
        System.out.println(describe(obj1));
        System.out.println(describe(obj2));
        System.out.println(describe(obj3));
    }
    // Java 17+ 支持类型模式匹配
    static String describe(Object obj) {
        return switch (obj) {
            case Integer i -> "整数: " + i;
            case String s && s.length() > 5 -> "长字符串: " + s;
            case String s -> "短字符串: " + s;
            case Double d -> "浮点数: " + d;
            case null -> "空值";
            default -> "其他类型: " + obj.getClass().getName();
        };
    }
}

实际应用场景

import java.time.DayOfWeek;
import java.time.LocalDate;
public class PracticalUse {
    public static void main(String[] args) {
        // 计算工资
        int workingDays = 22;
        double salary = calculateSalary(8000, workingDays, "senior");
        System.out.printf("本月工资: %.2f 元%n", salary);
        // 获取当天安排
        System.out.println(getSchedule(LocalDate.now().getDayOfWeek()));
        // 简单状态机
        System.out.println(nextState("TO_DO"));
        System.out.println(nextState("IN_PROGRESS"));
    }
    // 工资计算
    static double calculateSalary(double base, int days, String level) {
        return switch (level) {
            case "junior" -> base * (days / 22.0) * 0.9;
            case "mid" -> base * (days / 22.0) * 1.0;
            case "senior" -> base * (days / 22.0) * 1.3;
            case "manager" -> {
                double bonus = days > 25 ? 2000 : 0;
                yield base * (days / 22.0) * 1.5 + bonus;
            }
            default -> throw new IllegalArgumentException("未知级别: " + level);
        };
    }
    // 获取当天安排
    static String getSchedule(DayOfWeek day) {
        return switch (day) {
            case MONDAY -> "周一:工作例会";
            case TUESDAY, THURSDAY -> "技术开发";
            case WEDNESDAY -> "团队协作";
            case FRIDAY -> "工作总结";
            case SATURDAY -> "自由时间";
            case SUNDAY -> "休息准备";
        };
    }
    // 状态机
    static String nextState(String currentState) {
        return switch (currentState) {
            case "TO_DO" -> "IN_PROGRESS";
            case "IN_PROGRESS" -> "IN_REVIEW";
            case "IN_REVIEW" -> "DONE";
            case "DONE" -> "COMPLETED";
            default -> currentState;
        };
    }
}

性能与便捷性对比

public class PerformanceComparison {
    public static void main(String[] args) {
        int num = 5000000;
        // 传统 Switch 性能测试
        long start1 = System.nanoTime();
        long sum1 = 0;
        for (int i = 0; i < num; i++) {
            sum1 += traditionalSwitch(i % 4);
        }
        long end1 = System.nanoTime();
        // Switch 表达式性能测试
        long start2 = System.nanoTime();
        long sum2 = 0;
        for (int i = 0; i < num; i++) {
            sum2 += switchExpression(i % 4);
        }
        long end2 = System.nanoTime();
        System.out.printf("传统Switch: %d ms%n", (end1 - start1) / 1_000_000);
        System.out.printf("Switch表达式: %d ms%n", (end2 - start2) / 1_000_000);
        System.out.printf("结果相同: %b%n", sum1 == sum2);
    }
    // 传统方法
    static int traditionalSwitch(int x) {
        int result;
        switch (x) {
            case 0: result = 10; break;
            case 1: result = 20; break;
            case 2: result = 30; break;
            case 3: result = 40; break;
            default: result = 0; break;
        }
        return result;
    }
    // Switch 表达式
    static int switchExpression(int x) {
        return switch (x) {
            case 0 -> 10;
            case 1 -> 20;
            case 2 -> 30;
            case 3 -> 40;
            default -> 0;
        };
    }
}
特性 描述
箭头语法 -> 避免穿透,更清晰
多值匹配 case 1, 2, 3 -> 简化代码
表达式返回值 Switch 可作为表达式返回结果
yield 关键字 在块中返回值
无变量作用域泄漏 每个 case 有独立作用域
无需 break 箭头语法自动 break
穷尽性检查 所有可能情况必须处理

注意事项

  1. 编译要求:Java 12+ 编译,若要在旧版本使用需加上 --release 12
  2. 默认分支:对于枚举类型或非穷尽情况,可能需要 default
  3. 返回值类型:所有分支必须返回相同类型。

这些案例展示了 Switch 表达式如何让代码更简洁、可读性更强,同时减少错误发生的可能性。

抱歉,评论功能暂时关闭!