Java21 LTS版本

一、前言

除了众所周知的 JEP 之外,Java 21 还有更多内容。首先请确认 java 版本:

$ java -version
openjdk version "21" 2023-09-19
OpenJDK Runtime Environment (build 21+35-2513)
OpenJDK 64-Bit Server VM (build 21+35-2513, mixed mode, sharing)

我们一起来看看 String 和它的朋友们 Collections、Date、Time、HttpClient、并发、Math 和 BigInteger 的新增一些 API。

二、String(Java21新增)

String 新增了 indexOf() 方法,允许在起始索引和结束索引之间查找单个字符或子字符串。


public int indexOf(int ch, int beginIndex, int endIndex);
public int indexOf(String str, int beginIndex, int endIndex);

示例:


String text = "牛牛帮";int index = text.indexOf("0", 5, 15);

三、Character(Java21新增)

Character 类新增了几个方法来支持 Emoji 表情符号,新增了五个方法:isEmoji()isEmojiComponent()isEmojiModifier()isEmojiModifierBase() 和 isEmojiPresentation()

public static boolean isEmoji(int codePoint);
public static boolean isEmojiPresentation(int codePoint);
public static boolean isEmojiModifier(int codePoint);
public static boolean isEmojiModifierBase(int codePoint);
public static boolean isEmojiComponent(int codePoint);
public static boolean isExtendedPictographic(int codePoint);

所有这些方法都接受一个 int 类型的码点作为参数,判断传入的码点是否具有对应的表情符号。

四、StringBuffer 和 StringBuilder(Java21新增)

StringBuffer 和 StringBuilder 新增了 repeat() 方法重复单个字符或字符串多次。

StringBuilder:

@Override
public StringBuilder repeat(int codePoint, int count);@Override
public StringBuilder repeat(CharSequence cs, int count);

StringBuffer:


@Override
public synchronized StringBuffer repeat(int codePoint, int count);@Override
public synchronized StringBuffer repeat(CharSequence cs, int count);

五、Charset(Java18)

Charset 新增了一个带 fallback 的 forName()方法。

public static Charset forName(String charsetName, Charset fallback);

六、正则分组优化(Java20)

提取地址中的省市区县,代码如下:

笔者有幸用过正则分组,需求是提取地址中的省市区县,代码如下:private static final Pattern PATTERN = Pattern.compile("(?<province>[^省]+自治区|.*?省|.*?行政区|.*?市)(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)(?<county>[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+区|.+镇)?(?<village>.*)");public static Map<String, String> getAddressResolution(String address) {Matcher matcher = PATTERN.matcher(address);String province, city, county, town, village;Map<String, String> row = new HashMap<>();while (matcher.find()) {province = matcher.group("province");row.put("province", province == null ? "" : province.trim());city = matcher.group("city");row.put("city", city == null ? "" : city.trim());county = matcher.group("county");row.put("county", county == null ? "" : county.trim());town = matcher.group("town");row.put("town", town == null ? "" : town.trim());village = matcher.group("village");row.put("village", village == null ? "" : village.trim());}return row;
}public static void main(String[] args) {String address = "湖南省长沙市岳麓区永青路668号";System.out.println(getAddressResolution(address));// {province=湖南省, city=长沙市, county=岳麓区, town=, village=永青路668号}
}

Matcher、MatchResult、Pattern 现在新增了 namedGroups() 相关方法, getAddressResolution() 方法简化成这样了:


public static Map<String, String> getAddressResolution(String address) {Matcher matcher = PATTERN.matcher(address);Map<String, String> row = new HashMap<>();if (matcher.matches()) {Map<String, Integer> groupMap = matcher.namedGroups();groupMap.forEach((key, group) -> row.put(key, matcher.group(group)));}return row;
}

七、集合

Collections 框架中添加了 SequencedCollection、SequencedSet 和 SequencedMap 三个接口(Java21 新增)。

interface SequencedCollection<E> extends Collection<E> {// new methodSequencedCollection<E> reversed();// methods promoted from Dequevoid addFirst(E);void addLast(E);E getFirst();E getLast();E removeFirst();E removeLast();
}interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {SequencedSet<E> reversed();    // covariant override
}interface SequencedMap<K,V> extends Map<K,V> {// new methodsSequencedMap<K,V> reversed();SequencedSet<K> sequencedKeySet();SequencedCollection<V> sequencedValues();SequencedSet<Entry<K,V>> sequencedEntrySet();V putFirst(K, V);V putLast(K, V);// methods promoted from NavigableMapEntry<K, V> firstEntry();Entry<K, V> lastEntry();Entry<K, V> pollFirstEntry();Entry<K, V> pollLastEntry();
}

添加这 3 个新接口后,Java 集合类图发生了变化,图示:

除了这些,现在还可以使用多个工厂方法创建具有给定初始容量的不同类型的 Map(Java19新增)。


HashMap.newHashMap(100);
HashSet.newHashSet(100);
LinkedHashMap.newLinkedHashMap(100);
LinkedHashSet.newLinkedHashSet(100);
WeakHashMap.newWeakHashMap(100);

 Map 创建看起来很简单,但实际上却有一些技巧。例如,HashMap 内部是基于数组构建的,当该数组装满时,它会被复制到一个更大的数组中。所以阿里《JAVA开发手册》也建议设置 HashMap 的初始容量。问题在于,实际上并不仅仅是复制,第一个数组的所有键值对都需要重新计算哈希值,以便放置在新数组的正确位置上。由于哈希值的计算取决于数组的大小,每个数组的存储位置很可能不同。因此,我们不能简单地将第一个数组的内容复制到第二个数组中。为了避免冲突,当数组达到 75% 的容量时,就被认为已经满了。因此,要创建一个可以存储 100 个键值对的 Map,实际上需要一个大小为 134 的数组。考虑到数组的大小必须是 2 的次方,因此实际上会创建一个大小为 256 的数组。这种计算很容易出错,所以现在有了一个工厂方法。现在我们只需要调用 newHashMap(size),传递所需的容量就好了。

八、日期和时间 API(Java19新增)

Date and Time API 的一个很好的增加功能是 DateTimeFormatter 的本地化支持ofLocalizedPattern() 工厂方法,传递一个字符串格式,它会生成一个本地化的模式。

DateTimeFormatterBuilder 也已更新,添加了一个 appendLocalized() 方法,用于添加一个本地化模式(类型为字符串)。


LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedPattern("yM");
System.out.println(now.format(formatter)); // 2023年9月

九、IO流

PrintStream 在 Java18 中新增了 charset()方法用于获取使用的字符集。

public Charset charset();

HttpClient、ExecutorService 和 ForkJoinPool 类在 17 和 21 之间实现了 AutoCloseable。现在可以使用 try-with-resources语句来创建实例。

十、Math 和 BigInteger

Math 类和 BigInteger 类也得到了一些关注。首先,Math类添加了一系列方法。


// 执行两个数字的向上取整除法运算,并返回大于或等于除法结果的最小整数。
public static int ceilDiv(int x, int y);
public static long ceilDiv(long x, int y);
public static long ceilDiv(long x, long y);// 执行两个数字的向上取整除法运算,但是在被除数不能被除数整除时,
// 会抛出ArithmeticException异常。
public static int ceilDivExact(int x, int y);
public static long ceilDivExact(long x, long y);// 这个方法返回的是两个数字进行向上取整除法运算后的余数。
public static int ceilMod(int x, int y);
public static int ceilMod(long x, int y);
public static long ceilMod(long x, long y);// 这个方法用于对两个数字进行整除运算,并确保结果是一个整数。
// 如果除数无法整除被除数,将会抛出ArithmeticException异常。
public static int divideExact(int x, int y);
public static long divideExact(long x, long y);// 执行两个数字的向下取整除法运算,但是在被除数不能被除数整除时,
// 会抛出ArithmeticException异常。
public static int floorDivExact(int x, int y);
public static long floorDivExact(long x, long y);

添加了 clamp() 方法可以处理 int、long、float 和 double 原始类型,将提供的值限制在给定的最小值和最大值之间。


public static int clamp(long value, int min, int max);
public static long clamp(long value, long min, long max);
public static double clamp(double value, double min, double max);
public static float clamp(float value, float min, float max);

 还有一个方法:unsignedMultiplyHigh(),用于将两个长整型数作为无符号数相乘,并将64位高位作为长整型返回。


public static long unsignedMultiplyHigh(long x, long y);

BigInteger 类增加了一个功能:在并行中执行乘法运算,使用了 Fork/Join 框架。

public BigInteger parallelMultiply(BigInteger val);

十一、Thread

关于 VirtualThread 的内容这里不做过多介绍,想必各位会在各种途径看到各式各样的文章。在这里,我只想介绍两个方面。

首先,Thread 现在添加了 join()方法和 sleep()方法,两者都接受 Duration 作为参数,Duration 语义化更加易用。另外就是 isVirtual()方法,用于判断线程是否为虚拟线程。


public static void sleep(Duration duration) throws InterruptedException;
public final boolean join(Duration duration) throws InterruptedException;
public final boolean isVirtual();

另外需要重点介绍的一个是在 Future 接口中添加的新方法。实际上有三个方法:

resultNow()exceptionNow() 这两个方法不会抛出已检查异常,因此代码中不再需要 try catch,使用起来更加方便。但请注意,如果调用这些方法并且使用的 Future 对象尚未完成,那么将会得到一个 IllegalStateException异常。需要在确保 Future 对象产生了结果或异常时调用这些方法。

第三个方法是 state(),可以调用它来检查 Future 对象的当前状态。返回值是一个新的枚举:Future.State。

enum State {/*** 表示任务尚未完成*/RUNNING,/*** 表示任务成功完成*/SUCCESS,/*** 表示任务完成但出现异常*/FAILED,/*** 表示任务被取消。*/CANCELLED
}

因此,通过这个API,现在可以更精确地监控任务的进展情况。

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

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

相关文章

activiti7的数据表和字段的解释

activiti7的数据表和字段的解释 activiti7版本有25张表&#xff0c;而activiti6有28张表&#xff0c;activiti5有27张表&#xff0c;绝大部分的表和字段的含义都是一样的&#xff0c;所以本次整理的activiti7数据表和字段的解释&#xff0c;也同样适用于activiti6和5。 1、总览…

pcl--第五节 点云表面法线估算

估算点云表面法线 * 表面法线是几何表面的重要属性&#xff0c;在许多领域&#xff08;例如计算机图形应用程序&#xff09;中大量使用&#xff0c;以应用正确的光源以产生阴影和其他视觉效果。 给定一个几何表面&#xff0c;通常很难将表面某个点的法线方向推断为垂直于该点…

CockroachDB集群部署

CockroachDB集群部署 1、CockroachDB简介 CockroachDB(有时简称为CRDB)是一个免费的、开源的分布式 SQL 数据库&#xff0c;它建立在一个事务性和强一致性的键 值存储之上。它由 PebbleDB(一个受 RocksDB/leveldb 启发的 K/B 存储库)支持&#xff0c;并使用 Raft 分布式共识…

TypeScript入门

目录 一&#xff1a;语言特性 二&#xff1a;TypeScript安装 NPM 安装 TypeScript 三&#xff1a;TypeScript基础语法 第一个 TypeScript 程序 四&#xff1a;TypeScript 保留关键字 空白和换行 TypeScript 区分大小写 TypeScript 注释 TypeScript 支持两种类型的注释 …

初识C语言——详细入门一(系统性学习day4)

目录 前言 一、C语言简单介绍、特点、基本构成 简单介绍&#xff1a; 特点&#xff1a; 基本构成&#xff1a; 二、认识C语言程序 标准格式&#xff1a; 简单C程序&#xff1a; 三、基本构成分类详细介绍 &#xff08;1&#xff09;关键字 &#xff08;2&#xf…

fork函数

二.fork函数 2.1函数原型 fork()函数在 C 语言中的原型如下&#xff1a; #include <unistd.h>pid_t fork(void);其中pid_t是一个整型数据类型&#xff0c;用于表示进程ID。fork()函数返回值是一个pid_t类型的值&#xff0c;具体含义如下&#xff1a; 如果调用fork()的…

MyBatis中当实体类中的属性名和表中的字段名不一样,怎么办

方法1&#xff1a; 在mybatis核心配置文件中指定&#xff0c;springboot加载mybatis核心配置文件 springboot项目的一个特点就是0配置&#xff0c;本来就省掉了mybatis的核心配置文件&#xff0c;现在又加回去算什么事&#xff0c;总之这种方式可行但没人这样用 具体操作&…

Python灰帽编程——错误异常处理与面向对象

文章目录 错误异常处理与面向对象1. 错误和异常1.1 基本概念1.1.1 Python 异常 1.2 检测&#xff08;捕获&#xff09;异常1.2.1 try except 语句1.2.2 捕获多种异常1.2.3 捕获所有异常 1.3 处理异常1.4 特殊场景1.4.1 with 语句 1.5 脚本完善 2. 内网主机存活检测程序2.1 scap…

【Java 基础篇】Java字符打印流详解:文本数据的输出利器

在Java编程中&#xff0c;我们经常需要将数据输出到文件或其他输出源中。Java提供了多种输出流来帮助我们完成这项任务&#xff0c;其中字符打印流是一个非常有用的工具。本文将详细介绍Java字符打印流的用法&#xff0c;以及如何在实际编程中充分利用它。 什么是字符打印流&a…

DNG格式详解,DNG是什么?为何DNG可以取代RAW统一单反相机、苹果安卓移动端相机拍摄输出原始图像数据标准

返回图像处理总目录&#xff1a;《JavaCV图像处理合集总目录》 前言 在DNG格式发布之前&#xff0c;我们先了解一下之前单反相机、苹果和安卓移动端相机拍照输出未经处理的原始图像格式是什么&#xff1f; RAW 什么是RAW&#xff1f; RAW是未经处理、也未经压缩的格式。可以…

Rust通用编程概念(3)

Rust通用编程概念 1.变量和可变性1.执行cargo run2.变量3.变量的可变性4.常量5.遮蔽5.1遮蔽与mut区别1.遮蔽2.mut 2.数据类型1.标量类型1.1整数类型1.2浮点数类型1.3数字运算1.4布尔类型1.5字符类型 2.复合类型2.1元组类型2.2数组类型1.访问数组2.无效的数组元素访问 3.函数3.1…

如何解决 503 Service Temporarily Unavailable?

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

想要精通算法和SQL的成长之路 - 填充书架

想要精通算法和SQL的成长之路 - 填充书架 前言一. 填充书架1.1 优化 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 填充书架 原题链接 题目中有一个值得注意的点就是&#xff1a; 需要按照书本顺序摆放。每一层当中&#xff0c;只要厚度不够了&#xff0c;当前层最高…

【考研数学】高等数学第六模块 —— 空间解析几何(1,向量基本概念与运算)

文章目录 引言一、空间解析几何的理论1.1 基本概念1.2 向量的运算 写在最后 引言 我自认空间想象能力较差&#xff0c;所以当初学这个很吃力。希望现在再接触&#xff0c;能好点。 一、空间解析几何的理论 1.1 基本概念 1.向量 —— 既有大小&#xff0c;又有方向的量称为向…

C语言指针,深度长文全面讲解

指针对于C来说太重要。然而&#xff0c;想要全面理解指针&#xff0c;除了要对C语言有熟练的掌握外&#xff0c;还要有计算机硬件以及操作系统等方方面面的基本知识。所以本文尽可能的通过一篇文章完全讲解指针。 为什么需要指针&#xff1f; 指针解决了一些编程中基本的问题。…

spring aop源码解析

spring知识回顾 spring的两个重要功能&#xff1a;IOC、AOP&#xff0c;在ioc容器的初始化过程中&#xff0c;会触发2种处理器的调用&#xff0c; 前置处理器(BeanFactoryPostProcessor)后置处理器(BeanPostProcessor)。 前置处理器的调用时机是在容器基本创建完成时&#xff…

Axure原型设计累加器计时器设计效果(职业院校技能大赛物联网技术应用项目原型设计题目)

目录 前言 一、本题实现效果 二、操作步骤 1.新建文件 2.界面设计 2.1文本框 2.2 按钮 2.3设计界面完成 3.交互 3.1启动交互设置 3.2 分别设置三个属性 3.2.1 设置值为“0” 3.2.2 文字于文本框 3.2.3 获取焦点时 3.3 停止按钮的交互动作 3.3.1 设置变量值 3.4 重…

私有化部署企业即时通讯(企业im)除了钉钉还有这些

在现代企业中&#xff0c;私有化部署企业即时通讯平台已经成为确保数据安全和实现高效通信的重要手段。除了众所周知的钉钉&#xff0c;WorkPlus作为领先品牌&#xff0c;提供私有化部署企业即时通讯的领先选择。本文将介绍WorkPlus为企业提供的广阔领域和精彩特点&#xff0c;…

详解FreeRTOS:FreeRTOS任务删除过程源码分析(进阶篇—2)

本篇博文讲解FreeRTOS中任务删除过程的源代码,帮助各位更好理解删除任务的原理和流程。 在详解FreeRTOS:FreeRTOS任务管理函数(基础篇—11)中,讲述了可以使用vTaskDelete()函数实现删除任务。 函数源码如下: 程序说明如下: (1)、调用函数 prvGetTCBFromHandle()获取要删…

MQTT Paho Android 支持SSL/TLS(亲测有效)

MQTT Paho Android 支持SSL/TLS(亲测有效) 登录时支持ssl的交互 这是调测登录界面设计 代码中对ssl/tls的支持 使用MqttAndroidClient配置mqtt客户端请求时&#xff0c;不加密及加密方式连接存在以下几点差异&#xff1a; url及端口差异 val uri: String if (tlsConnect…