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

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

什么是模式匹配?

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

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

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

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

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

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 中引入。它允许您使用更简洁的语法来检查对象的类型和提取其值。

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

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

以下是一个简单的示例:

Object obj = "Hello, world!";if (obj instanceof String str) {System.out.println(str.toUpperCase());
}

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

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

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

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

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

  • 类型模式:用于匹配特定类型的对象。
Object obj = 123;if (obj instanceof Integer i) {System.out.println(i * 2);
}
  • 记录模式:用于匹配具有特定属性的记录。
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 + "!");
}
  • 数组模式:用于匹配数组。
int[] numbers = {1, 2, 3};if (numbers instanceof int[] arr && arr.length == 3) {System.out.println("The array contains three elements.");
}

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

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之前,我们实现同样的功能需要这样写:

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语言的模式匹配。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/479559.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单片机学习笔记---红外遥控(外部中断)

目录 红外遥控简介 硬件电路 基本发送与接收 NEC编码​​​​​​​ 遥控器键码 复习外部中断和定时器 红外遥控简介 红外遥控是利用红外光进行通信的设备,由红外LED将调制后的信号发出,由专用的红外接收头进行解调输出 通信方式:单工…

余弦退火:通过动态调整学习率增强深度学习

导 读 在快速发展的机器学习领域,特别是深度学习,训练算法的效率和有效性至关重要。学习率作为这些算法的一个关键因素,决定了梯度下降期间的步长。 而余弦退火作为用于优化学习率的一种新颖且日益流行的技术。本文将深入探讨了余弦退火的概…

SwiftUI 更自然地向自定义视图传递参数的“另类”方式

概览 在 SwiftUI 中,正是自定义视图让我们的 App 变得与众不同!然而,除了传统的视图接口定义方式以外,我们其实还可以有更“银杏化”的选择。 如上图所示:对于 SubView 子视图所需的参数我们一开始并没有操之过急&…

软件工具安装遇到bug、报错不知道怎么解决?看这里!

前言 本文举例了几个常见的软件工具使用问题,文末会提供一些我自己整理和使用的工具资料 。 "在追逐零 Bug 的路上,我们不断学习、改进,更加坚定自己的技术信念。让我们相信,每一个 Bug 都是我们成长的机会。" 一、VM…

【Java EE初阶十五】网络编程TCP/IP协议(二)

1. 关于TCP 1.1 TCP 的socket api tcp的socket api和U大片的socket api差异很大,但是和前面所讲的文件操作很密切的联系 下面主要讲解两个关键的类: 1、ServerSocket:给服务器使用的类,使用这个类来绑定端口号 2、Socket&#xf…

如何使用IP代理解决亚马逊账号IP关联问题?

亚马逊账号IP关联问题是指当同一个IP地址下有多个亚马逊账号进行活动时,亚马逊会将它们关联在一起,从而可能导致账号被封禁或限制。 为了避免这种情况,许多人选择使用IP代理。 IP代理为什么可以解决亚马逊IP关联问题? IP代理是…

15-55V输入自动升降压 光伏MPPT自动跟踪充电方案 大功率300瓦

1.MPPT原理--简介 MPPT,全称为Maximum Power Point Tracking,即最大功点跟踪,它是一种通过调节电气模块的工作状态,使光伏板能够输出更多电能的电气系统能够将太阳能电池板发出的直流电有效地贮存在蓄电池中,可有效地…

ITK 图像分割(一):阈值ThresholdImageFilter

效果: Video: 区域增加分割 1、itkThresholdImageFilter 该类的主要功能是通过设置低阈值、高阈值或介于高低阈值之间,则将图像值输出为用户指定的值。 如果图像值低于、高于或介于设置的阈值之间,该类就将图像值设置为用户指定的“外部”值…

《Solidity 简易速速上手小册》第3章:Solidity 语法基础(2024 最新版)

文章目录 3.1 变量和类型3.1.1 基础知识解析详细解析变量类型深入数据类型理解变量可见性 3.1.2 重点案例:创建一个简单的存储合约案例 Demo:编写一个简单的数字存储合约案例代码:SimpleStorage.sol在 Remix 中进行交互:拓展操作&…

Java使用Redis实现消息队列

近期刷Java面试题刷到了“如何使用Redis实现消息队列”,解答如下: 一般使用 list 结构作为队列, rpush 生产消息, lpop 消费消息。当 lpop 没有消息的时候,要适当sleep 一会再重试。若不使用sleep,则可以用…

解决npm淘宝镜像到期问题

1 背景 由于node安装插件是从国外服务器下载,如果没有“特殊手法”,就可能会遇到下载速度慢、或其它异常问题。 所以如果npm的服务器在中国就好了,于是我们乐于分享的淘宝团队干了这事。你可以用此只读的淘宝服务代替官方版本,且…

Vue源码系列讲解——生命周期篇【一】(综述)

1. 前言 在Vue中,每个Vue实例从被创建出来到最终被销毁都会经历一个过程,就像人一样,从出生到死亡。在这一过程里会发生许许多多的事,例如设置数据监听,编译模板,组件挂载等。在Vue中,把Vue实例…