Java switch 表达式
最后修改于 2025 年 5 月 31 日
在本文中,我们将展示如何在 Java 中使用 switch 表达式。
Switch 表达式提供了一种更简洁、更易读的方式来编写多路分支逻辑。 它们是对经典 switch 语句的强大增强。
与传统的 switch 语句不同,switch 表达式可以返回值。
Java switch 表达式支持使用多个 case 标签。 这些也称为分支。 每个 case 标签后跟 -> 箭头语法。
switch 表达式必须是穷尽的。 除了少数情况(例如枚举,编译器可以确定所有可能的选项)外,我们必须使用 default 分支。 当没有其他选项匹配时,它将被执行。
void main() {
System.out.print("Enter a domain: ");
try (var sc = new Scanner(System.in)) {
String domain = sc.nextLine();
domain = domain.trim().toLowerCase();
switch (domain) {
case "us" -> System.out.println("United States");
case "de" -> System.out.println("Germany");
case "sk" -> System.out.println("Slovakia");
case "hu" -> System.out.println("Hungary");
default -> System.out.println("Unknown");
}
}
}
要求用户输入域名。 域名被读取并存储在一个变量中。 该变量使用 switch 关键字针对选项列表进行测试。 在我们的程序中,我们有一个域名变量。 我们从命令行读取该变量的值。
case "us" -> System.out.println("United States");
我们使用 case 语句来测试变量的值。 有几个选项。 例如,如果该值等于“us”,则将“United States”字符串打印到控制台。 一旦选项匹配,就不会评估其他分支。
default -> System.out.println("Unknown");
当该值与任何先前的分支不匹配时,将执行 default 分支。
使用枚举
在下一个示例中,我们将使用枚举。
void main() {
Season season = Season.randomSeason();
String msg = switch (season) {
case Season.SPRING -> "Spring";
case Season.SUMMER -> "Summer";
case Season.AUTUMN -> "Autumn";
case Season.WINTER -> "Winter";
};
System.out.println(msg);
}
enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER;
public static Season randomSeason() {
var random = new Random();
int ridx = random.nextInt(Season.values().length);
return Season.values()[ridx];
}
}
我们定义一个 Season 枚举。 该枚举包含一个 randomSeason 方法,该方法随机创建一个 Season 值。 根据选择的值,我们打印一条消息。
var msg = switch (season) {
case Season.Spring -> "Spring";
case Season.Summer -> "Summer";
case Season.Autumn -> "Autumn";
case Season.Winter -> "Winter";
};
System.out.println(msg);
我们根据 switch 表达式检查该值。 该表达式返回枚举的字符串表示形式。 请注意,switch 表达式是穷尽的。
检查多个选项
我们可以在一个分支中检查多个选项。
void main() {
Grade grade = Grade.randomGrade();
String msg = switch (grade) {
case Grade.A, Grade.B, Grade.C, Grade.D, Grade.E, Grade.F -> "passsed";
case Grade.FX -> "failed";
};
System.out.printf("%s - %s", grade - msg");
}
enum Grade {
A, B, C, D, E, F, FX;
public static Grade randomGrade() {
var random = new Random();
int rdx = random.nextInt(Grade.values().length);
return Grade.values()[rdx];
}
}
我们有一个成绩列表。对于 A 到 F 的成绩,我们通过了示例。对于 FX 成绩,我们考试不及格。
String msg = switch (grade) {
case Grade.A, Grade.B, Grade.C, Grade.D, Grade.E, Grade.F -> "passsed";
case Grade.FX -> "failed";
};
我们在第一个分支中检查六个选项。 它们用逗号分隔。
检查类型
在以下程序中,我们检查值的类型。
void main() {
List<Object> objects = List.of("falcon", new BigDecimal(120001212),
new int[] { 1, 2, 3, 4, 5 }, new String[] { "sky", "blue", "rock" });
objects.forEach(e -> System.out.println(checkType(e)));
}
String checkType(Object o) {
return switch (o) {
case String str -> "String";
case BigDecimal bd -> "BigDecimal";
case Integer i -> "Integer";
case int[] ai -> "Array of integers";
case String[] as -> "Array of strings";
default -> "n/a";
};
}
我们有一个包含各种类型的对象的列表。 使用 switch 表达式,我们确定每个值的类型。
return switch (o) {
case String str -> "String";
case BigDecimal bd -> "BigDecimal";
case Integer i -> "Integer";
case int[] ai -> "Array of integers";
case String[] as -> "Array of strings";
default -> "n/a";
};
在 case 关键字之后,我们提供类型。 如果类型匹配,则执行该分支并返回相应的字符串。
When 守卫
When 守卫可用于在选项上应用简单的表达式。 可以将表达式与 && 和 || 运算符组合使用。
void main() {
int[] ages = { 12, 23, 45, 0, 67, 88, 43, 55, -4};
Arrays.stream(ages).forEach(e -> System.out.printf("%s - %s%n", e, checkAge(e)));
}
String checkAge(Integer age) {
return switch (age) {
case Integer i when i < 18 && i > 0-> "minor";
case Integer i when i >= 18 && i < 64 -> "adult";
case Integer i when i > 64 -> "senior";
default -> "n/a";
};
}
我们有一个表示年龄的整数数组。 我们使用 switch 表达式将这些值映射到年龄类别。
return switch (age) {
case Integer i when i < 18 && i > 0-> "minor";
case Integer i when i >= 18 && i < 64 -> "adult";
case Integer i when i > 64 -> "senior";
default -> "n/a";
};
在 when 关键字之后,我们使用 < 18 && i > 0-> 表达式来检查该数字是否在 0 到 18 之间。
Null 值
可以在 switch 表达式中检查 null 值。
void main() {
List<Integer> data = new ArrayList<>();
data.add(2);
data.add(5);
data.add(0);
data.add(null);
data.add(-4);
data.add(6);
data.forEach(e -> System.out.printf("%s - %s%n", e, checkValue(e)));
}
String checkValue(Integer i) {
return switch (i) {
case null -> "null value";
case 0 -> "zero value";
case Integer n when n > 0 -> "positive value";
case Integer n when n < 0 -> "negative value";
default -> "n/a";
};
};
我们有一个整数列表;还有一个 null 值。
case null -> "null value";
此分支检查该值是否为 null。
记录字段
可以在 when 守卫中检查记录字段。
void main() {
var points = List.of(Point.of(0, 0), Point.of(-3, -3), Point.of(-3, -3),
Point.of(12, -1));
points.forEach(p -> System.out.printf("%s - %s%n", p, checkQuadrant(p)));
}
String checkQuadrant(Point p) {
return switch (p) {
case Point(var x, var y) when x == 0 && y == 0 -> "origin";
case Point(var x, var y) when x > 0 && y > 0 -> "Q I";
case Point(var x, var y) when x < 0 && y > 0 -> "Q II";
case Point(var x, var y) when x < 0 && y < 0 -> "Q III";
case Point(var x, var y) when x > 0 && y < 0 -> "Q IV";
default -> "n/a";
};
};
record Point(int x, int y) {
static Point of(int x, int y) {
return new Point(x, y);
}
}
我们有一个坐标系中的点列表。 我们将每个点映射到其对应的象限。
return switch (p) {
case Point(var x, var y) when x == 0 && y == 0 -> "origin";
case Point(var x, var y) when x > 0 && y > 0 -> "Q I";
case Point(var x, var y) when x < 0 && y > 0 -> "Q II";
case Point(var x, var y) when x < 0 && y < 0 -> "Q III";
case Point(var x, var y) when x > 0 && y < 0 -> "Q IV";
default -> "n/a";
};
记录遵循 case 关键字。 在 when 守卫之后,我们可以直接在表达式中使用这些字段。
使用 Switch 表达式实现 FizzBuzz
你可以使用带有 when 守卫的 switch 表达式,以简洁且具有表现力的方式实现经典的 FizzBuzz 问题。 这种方法利用模式匹配和守卫来干净利落地处理多个条件。
void main() {
IntStream.range(1, 101).forEach(this::doFizzBuzz);
}
void doFizzBuzz(int e) {
switch (e) {
case int n when n % 3 == 0 && n % 5 == 0 -> System.out.println("FizzBuzz");
case int n when n % 3 == 0 -> System.out.println("Fizz");
case int n when n % 5 == 0 -> System.out.println("Buzz");
default -> System.out.println(e);
}
}
在此示例中,doFizzBuzz 方法使用带有 when 守卫的 switch 表达式,对可被 3 整除的数字打印 "Fizz",对可被 5 整除的数字打印 "Buzz",对既可被 3 整除又可被 5 整除的数字打印 "FizzBuzz"。 所有其他数字都按原样打印。 这演示了 switch 表达式如何简化复杂的条件逻辑。
来源
在本文中,我们讨论了 Java 中的 switch 表达式。
作者
列出所有Java教程。