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.rhkb.cn/news/136360.html

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

相关文章

zemax像质评价

1、外形图 1.1二维外形图 如图所示&#xff0c;展示镜头的侧面图 可以通过设置改变图中显示的内容&#xff1a; 起始面&#xff1a;绘图的第一个面 终止面&#xff1a;绘图的最后一个面 光线数&#xff1a;画出的光线数&#xff08;上图中的一个颜色就是7根线&#xff09; …

使用Visual Leak Detector排查内存泄漏问题

目录 1、VLD工具概述 2、下载并安装VLD 2.1、下载VLD 2.2、安装VLD 3、VLD安装目录及文件说明 3.1、安装目录及文件说明 3.2、关于32位和64位版本的详细说明 4、在工程中引入VLD 5、内存泄漏检测实例讲解 5.1、程序启动报错 5.2、启动调试&#xff0c;查看内存泄漏报…

【深度学习-第3篇】使用MATLAB快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例

在本文中&#xff0c;我们将介绍如何使用 MATLAB 中的 Convolutional Neural Network&#xff08;CNN&#xff09;进行分类任务。我们将使用 MATLAB 的 Deep Learning Toolbox 来创建、训练和评估 CNN。 一、一个简单的案例 1 安装和准备 首先&#xff0c;确保已安装 MATLAB…

Prometheus+Grafana可视化监控【Redis状态】

文章目录 一、安装Docker二、安装Redis数据库(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装redis_exporter七、Grafana添加Redis监控模板 一、安装Docker 注意&#xff1a;我这里使用之前写好脚本进行安装Docker&#xff0c;如果已…

华为云云耀云服务器L实例评测|认识redis未授权访问漏洞 漏洞的部分复现 设置连接密码 redis其他命令学习

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到过MySQL数据库被攻击的情况&#xff0c;数据丢失&#xff0c;还好我有几份备份&#xff0c;没有造成太大的损失。昨天收到华为云的邮箱提醒&#xff0c;我的redis数据库没有设置密码&…

人声分离网站,帮你快速提取视频中的人声和背景音乐

今天给大家带来一个可以分离人声的网站——音分轨&#xff0c;他运用人工智能算法可以将音频中的人声部分和音乐部分分离&#xff0c;使我们的视频制作过程可以更方便。 我们点击右下角“选择文件”上传一个音频&#xff0c;上传好音频后&#xff0c;人工智能就开始处理我们上传…

使用Chatgpt编写的PHP数据库pdo操作类(增删改查)

摘要 将PDO封装成PHP类进行调用有很多好处&#xff0c;包括&#xff1a; 1、封装性和抽象性&#xff1a; 通过将PDO封装到一个类中&#xff0c;您可以将数据库操作逻辑与应用程序的其他部分分离开来&#xff0c;提高了代码的组织性和可维护性。这样&#xff0c;您只需在一个地…

python 学习笔记(6)—— Flask 、MySql

目录 Flask 1、起步 2、渲染项目的首页 3、处理无参数的 GET 请求 4、处理有 query 参数的 GET 请求 6、处理 params 参数的 get 请求 6、处理 application/json 类型请求体的 POST 请求 7、根据参数渲染模板页面 8、上传文件 数据库操作&#xff08;mysql&#xff0…

vue移动端页面适配

页面的适配&#xff0c;就是一个页面能在PC端正常访问&#xff0c;同时也可以在移动端正正常访问。 现在我们可以通过弹性布局【Flexible布局】、媒体查询和响应式布局。除此之外&#xff0c;还可以通过rem和vw针对性地解决页面适配问题。 响应式布局 响应式布局的核心&…

公司需要同步大量数据,如何缓解传输压力提高同步效率?

数据同步是很多企业在面临各类需求时要进行的事项&#xff0c;但由于体量较大&#xff0c;往往出现了很多的问题&#xff0c;很会影响企业人员的时间和效率。如何缓解传输压力&#xff0c;提高同步效率&#xff0c;保证同步质量&#xff0c;成为企业关注的重点问题。本文将从以…

【少儿编程的网站应该怎么选择】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;效率…

【JAVA】多态的概念与实际利用

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 前言 在面向对象(OOP)的程序设计语言中&#xff0c;多态与封装、继承合称为OOP的三大特性。在今天&#xff0c;我们就来学习一下JAVA中的多态是什么样子的。、 多态 指一个对象在不同…

【MySQL进阶】SQL性能分析

一、SQL性能分析 1.SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信 息。通过如下指令&#xff0c;可以查看当前数据库的 INSERT 、 UPDATE 、 DELETE 、 SELECT 的访问频次&#xff1a; -- session 是查看当…

网站登录界面制作(three.js 3D特效背景)+ boostrap导航栏实现 + jQuery移动窗口【附加源代码】

网站登录界面制作&#xff08;three.js 3D特效背景&#xff09; boostrap导航栏实现 文章目录 网站登录界面制作&#xff08;three.js 3D特效背景&#xff09; boostrap导航栏实现前言登录界面效果图主页面效果图&#xff1a;主页面源代码 前言 学过Web前端的许多小伙伴都会面…

五、Java基本数据类型

Java基本数据类型 Java基本数据类型1.1.整数类型1.1.1.int型1.1.2.byte型1.1.3.short型1.1.4.long型 1.2.浮点类型1.3.字符类型1.3.1.char型1.3.2.转义字符 1.4.布尔类型 —————————————————————————————————————————————————…

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

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

mysql redis的区别

.mysql和redis的数据库类型 mysql是关系型数据库&#xff0c;主要用于存放持久化数据&#xff0c;将数据存储在硬盘中&#xff0c;读取速度较慢。 redis是NOSQL&#xff0c;即非关系型数据库&#xff0c;也是缓存数据库&#xff0c;即将数据存储在缓存中&#xff0c;缓存的读取…

UI 自动化测试框架:PO 模式+数据驱动 【详解版】

目录 1. PO 设计模式简介 什么是 PO 模式&#xff1f; PO 模式的优点 2. 工程结构简介 工程结构 框架特点 3. 工程代码示例 page 包 action 包 business_process 包 util 包 conf 包 1. PO 设计模式简介 什么是 PO 模式&#xff1f; PO&#xff08;PageObject&am…

PHP8中字符串与数组的转换-PHP8知识详解

在php8中使用explode()函数和implode()函数实现字符串和数组之间的转换。 1、使用explode()函数把字符串按照一定的规则拆分为数组中的元素&#xff0c;并且形成数组。 使用explode()函数把字符串转换数组&#xff0c;示范代码&#xff1a; <?php $string "html,cs…

基于webman的CMS,企业官网通用PHP后台管理系统

2023年9月11日10:47:00 仓库地址&#xff1a; https://gitee.com/open-php/zx-webman-website 还有laravelscui的版本目前还未开源&#xff0c;电商laravel版本差不多&#xff0c;后续在移植webman 算是比较标准的phpvue的项目 CMS&#xff0c;企业官网通用PHP后台管理系统 …