模式匹配这么好,Java语法里有吗?

这篇文章我们借助新版Java来理解模式匹配,Rust版的模式匹配稍后就端上来,各位先尝尝Java这杯老咖啡还香不香😄。

什么是模式匹配?

下图直观的表达了模式匹配的概念。

所谓模式 类似上图中木盒的各种形状的洞洞,我们的值只有匹配木盒上面的洞洞才能放进去。 我们看到上面的和木盒有很多不同的形状,意味着模式是多种多样的。

模式匹配是一种通用的技术,可以用于匹配各种类型的数据,包括字符串、树、列表等。例如,正则表达式就是一种特殊类型的模式匹配,专门用于匹配字符串。

正则表达式 使用一系列特殊字符来定义模式。例如,正则表达式 \d+ 可以匹配任何由一个或多个数字组成的字符串。

我们把模式和匹配分开来看。

java 复制代码
Pattern pattern = Pattern.compile("\\d+");
String text = "12345abc67890";

Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
	System.out.println("The matched substring is: " + matcher.group());
}

// 程序输出:
The matched substring is: 12345
The matched substring is: 67890

这段代码中模式 就是Pattern对象,匹配 就是Matcher对象。程序运行过程就是,先创建一个模板有一个或多个数字,然后在text字符串中匹配出符合模板的字符串,最后print到标准输出。

理解了模式匹配这个概念以后,我们就来看新版Java中的模式匹配语法。到这里还不懂模式匹配请趴网线敲我。


Java中的模式匹配

Java 中的模式匹配是一种新的语言特性,于 Java 14 中引入。它允许您使用更简洁的语法来检查对象的类型和提取其值。

模式匹配由两个部分组成:

  • 模式:描述要匹配的对象,描述了数据的形状。
  • 绑定变量:用于存储从匹配对象中提取的值。

以下是一个简单的示例:

java 复制代码
Object obj = "Hello, world!";

if (obj instanceof String str) {
  System.out.println(str.toUpperCase());
}

在这个例子中,模式是 String str。它描述了一个类型为 String 的对象。绑定变量是 str,它用于存储从匹配对象中提取的值。

如果 obj 变量引用一个 String 对象,则模式匹配将成功。那么,我们说obj的值是匹配String模式的。然后,str 变量将包含该对象的字符串值。

模式匹配可以用于各种场景,包括:

  • 检查对象的类型
  • 从对象中提取值
  • 将对象转换为不同的类型

以下是一些更高级的模式匹配示例:

  • 类型模式:用于匹配特定类型的对象。
java 复制代码
Object obj = 123;

if (obj instanceof Integer i) {
  System.out.println(i * 2);
}
  • 记录模式:用于匹配具有特定属性的记录。
java 复制代码
record Person(String name, int age) {}

Person person = new Person("John Doe", 30);

if (person instanceof Person(String name, 30)) {
  System.out.println("Hello, " + name + "!");
}
  • 数组模式:用于匹配数组。
java 复制代码
int[] numbers = {1, 2, 3};

if (numbers instanceof int[] arr && arr.length == 3) {
  System.out.println("The array contains three elements.");
}

从 Java 17 开始,switch 语句也支持了模式匹配。

java 复制代码
Object obj = ...;

String name;

switch (obj) {
  case Person person:
    name = person.getName();
    break;
  case Company company:
    name = company.getName();
    break;
  default:
    throw new IllegalArgumentException("The object is not a Person or Company");
}

在Java 17之前,我们实现同样的功能需要这样写:

java 复制代码
Object obj = ...;

String name;

if (obj instanceof Person) {
  name = ((Person) obj).getName();
} else if (obj instanceof Company) {
  name = ((Company) obj).getName();
} else {
  throw new IllegalArgumentException("The object is not a Person or Company");
}

这段代码看起来不怎么优雅,不过它实现了同样的功能。

总结

从广义上说,模式匹配是一种"设计模式",不止编程语言,各种领域都有这种思想。从编程语言这个领域来看,它是先定义好模板,然后看数据是否符合这个模板,主要用于需要判断的场景。同时模式匹配不是必须的,它是一种高级的语法糖,即便没有模式匹配,功能也一样能实现。它的好处是提供了一种更加简洁的表达方式。

Java这个老古董都支持模式匹配,在Rust中肯定也支持了,下篇文章我们介绍Rust语言的模式匹配。

相关推荐
Sammyyyyy1 天前
Rust 1.92.0 发布:Never Type 进一步稳定
java·算法·rust
alonewolf_991 天前
深入解析G1与ZGC垃圾收集器:原理、调优与选型指南
java·jvm·算法
小镇学者1 天前
【c++】C++字符串删除末尾字符的三种实现方法
java·开发语言·c++
rfidunion1 天前
springboot+VUE+部署(1。新建项目)
java·vue.js·spring boot
小翰子_1 天前
Spring Boot整合Sharding-JDBC实现日志表按月按周分表实战
java·spring boot·后端
weixin_399380691 天前
OA 系统假死问题分析与优化
java·运维
豆沙沙包?1 天前
2026年--Lc334-2130. 链表最大孪生和(链表转数组)--java版
java·数据结构·链表
柒.梧.1 天前
SSM常见核心面试问题深度解析
java·spring·面试·职场和发展·mybatis
踏浪无痕1 天前
SQLInsight:从JDBC底层到API调用的零侵入SQL监控方案
数据库·后端·开源
杨章隐1 天前
Java 解析 CDR 文件并计算图形面积的完整方案(支持 MultipartFile / 网络文件)@杨宁山
java·开发语言