1 一文了解Java 21的新功能-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文了解Java 21的新功能

jf_ro2CN3Fa 来源:medium.com 2023-12-21 16:19 次阅读

来源:medium.com

JDK 21 于 2023 年 9 月 19 日发布,是继之前的 LTS 版本 JDK 17 之后最新的长期支持 (LTS) 版本。在本文中,我们将探讨 JDK 21 新引入的功能。

以下是 JDK 21 的新功能列表:

虚拟线程

序列集合

记录模式

字符串模板(预览)

未命名模式和变量(预览)

未命名类和实例主要方法(预览)

作用域值(预览)

结构化并发(预览)

1 虚拟线程

Java 代码的角度来看,虚拟线程感觉就像普通线程,但它们没有 1:1 映射到操作系统/平台线程。它是从虚拟线程到载体线程进而到操作系统线程的M:N映射。

有一个所谓的载体线程池,虚拟线程临时映射(“安装”)到该线程池上。一旦虚拟线程遇到阻塞操作,虚拟线程就会从载体线程中移除(“卸载”),并且载体线程可以执行另一个虚拟线程(新的或之前被阻塞的虚拟线程)。

载体线程池是ForkJoinPool

d9d291e0-9740-11ee-8b88-92fbcf53809c.png

虚拟线程的一些优点:

提高应用程序吞吐量

提高应用程序可用性

减少内存消耗

创建虚拟线程

要创建虚拟线程,我们可以使用 Thread.ofVirtual() 工厂方法并传递可运行对象。

Thread.ofVirtual().start(Runnable);

Thread.ofVirtual().unstarted(Runnable);

如果你想让虚拟线程立即启动,你可以使用start() 方法,它会立即执行传递给它的Runnable start()。

如果不希望虚拟线程立即启动,可以使用该unstarted()方法。

创建使用虚拟线程的ExecutorService

我们只需要替换newFixedThreadPool为newVirtualThreadPerTaskExecutor

importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;

publicclassVirtualThreadExample{

publicstaticvoidmain(String[]args){
ExecutorServiceexecutor=Executors.newVirtualThreadPerTaskExecutor();

executor.submit(()->{
System.out.println(Thread.currentThread().getName())
});

executor.shutdown();
}
}

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

项目地址:https://github.com/YunaiV/ruoyi-vue-pro

视频教程:https://doc.iocoder.cn/video/

2 顺序集合

顺序集合为我们提供了defined encounter order(是一种所见即所得的顺序,含义是从队列中取出元素的顺序既是你存放该元素时候的顺序),用于访问第一个和最后一个元素并以相反的顺序迭代。

这意味着我们可以在集合的两端添加、检索或删除元素。

d9e8a2b4-9740-11ee-8b88-92fbcf53809c.png

publicinterfaceSequencedCollectionextendsCollection{
defaultvoidaddFirst(Ee){...}
defaultvoidaddLast(Ee){...}
defaultEgetFirst(){...}
defaultEgetLast(){...}
defaultEremoveFirst(){...}
defaultEremoveLast(){...}
SequencedCollectionreversed();
}

正如我们所看到的,除了reverse()之外的所有方法都是默认方法并提供默认实现。

这意味着现有的集合类(例如 ArrayList 和 LinkedList)都可以实现此接口,而无需更改其代码。

ArrayListlist=newArrayList<>();
list.add(1);//[1]
list.addFirst(0);//[0,1]
list.addLast(2);//[0,1,2]
list.getFirst();//0
list.getLast();//2
list.reversed();//[2,1,0]

SequencedSet

SequencedSet 接口对于具有有序元素的 Set 非常有用,特别是当您必须执行某些操作(例如检索或删除第一个或最后一个索引处的元素)时。它还提供了一种反转元素的方法。

您还需要知道两个 SequencedSet 对象的比较与其他类型的 Set 相同,不依赖于元素顺序。

interfaceSequencedSetextendsSet,SequencedCollection{
SequencedSetreversed();
}

LinkedHashSet 是 Set 的一个实现,它实现了 SequencedSet 接口。

因此,您可以使用 LinkedHashSet 来创建 SequencedSet。

Set 的其他实现(例如 HashSet 和 TreeSet)未实现该接口。

让我们探索一些示例来演示如何访问第一个和最后一个元素,以及如何使用反向函数:

SequencedSetvalues=newLinkedHashSet<>();
values.add("one");
values.add("two");
System.out.println(values);//[one,two]

values.addFirst("zero");
System.out.println(values);//[zero,one,two]
values.addFirst("one");
System.out.println(values);//[one,zero,two]

values.addLast("three");
System.out.println(values);//[one,zero,two,three]

values.removeFirst();
System.out.println(values);//[zero,two,three]

SequencedSetreversedSet=values.reversed();
System.out.println(reversedSet);//[three,two,zero]

booleanisEqual=values.equals(reversedSet);
System.out.println(isEqual);//true
System.out.println(values.hashCode());//612888
System.out.println(reversedSet.hashCode());//612888
System.out.println(values.hashCode()==reversedSet.hashCode());//true

SequencedMap

如果要使用 SequencedMap 中定义的新方法,则需要使用 Map 实现,例如 LinkedHashMap 或实现 SortedMap 的 Map。

HashMap 不利用 Sequenced Collections,因为它没有定义 defined encounter order(是一种所见即所得的顺序,含义是从队列中取出元素的顺序既是你存放该元素时候的顺序)。

interfaceSequencedMapextendsMap{
SequencedMapreversed();
SequencedSetsequencedKeySet();
SequencedCollectionsequencedValues();
SequencedSet>sequencedEntrySet();
VputFirst(K,V);
VputLast(K,V);
EntryfirstEntry();
EntrylastEntry();
EntrypollFirstEntry();
EntrypollLastEntry();
}

在下面的示例中,正如您所看到的,我们可以通过firstEntry()和lastEntry()方法访问第一个和最后一个元素。

pollFirstEntry()方法将删除并返回第一个键值元素,如果映射为空,则返回 null。

此外,调用reverse()只会比较元素,而不依赖于它们的顺序。

SequencedMapmyMap=newLinkedHashMap<>();
myMap.put("one",1);
myMap.put("two",2);
System.out.println(myMap);//{one=1,two=2}

EntryfirstEntry=myMap.firstEntry();
System.out.println(firstEntry);//one=1

EntrylastEntry=myMap.lastEntry();
System.out.println(lastEntry);//two=2

myMap.putFirst("zero",0);
System.out.println(myMap);//{zero=0,one=1,two=2}
myMap.putFirst("one",-1);
System.out.println(myMap);//{one=-1,zero=0,two=2}

EntrypolledFirstEntry=myMap.pollFirstEntry();
System.out.println(polledFirstEntry);//one=-1
System.out.println(myMap);//{zero=0,two=2}

SequencedMapreversedMap=myMap.reversed();
System.out.println(reversedMap);//{two=2,zero=0}

booleanisEqual=myMap.equals(reversedMap);
System.out.println(isEqual);//true
System.out.println(myMap.hashCode());//692224
System.out.println(reversedMap.hashCode());//692224
System.out.println(myMap.hashCode()==reversedMap.hashCode());//true

3 字符串模板

这是预览功能,默认禁用,我们需要使用

--enable-preview启用字符串模板。

首先,在深入探讨字符串模板之前,我将探讨一些用于组合字符串的技术。

+(加号)运算符: 最大的缺点是每次使用 + 运算符时都会创建一个新字符串。

StringBuffer 和 StringBuilder: StringBuffer 是线程安全的,而 StringBuilder 是在 Java 5 中添加的,性能更高,但不是线程安全的替代方案。

它们的主要缺点是冗长,尤其是对于更简单的字符串:

vargreeting=newStringBuilder()
.append("Hello,welcome")
.append(name)
.toString();

String::format 和 String::formatter: 它们允许可重用模板,但它们要求我们指定格式并以正确的顺序提供变量。

varformat="Goodmorning%s,It'sabeautifulday!";
vartext=String.format(format,name);
//Java15+
vartext=format.formatter(name);

尽管我们节省了字符串分配的数量,但现在 JVM 必须解析/验证模板字符串。

java.text.MessageFormat: 与String格式相同,但更详细

varformat=newMessageFormat("Goodmorning{0},It'sabeautifulday!");
vargreeting=format.format(name);

现在我们有字符串模板来拯救

它简单、简洁,处理字符串的新方法称为模板表达式。它们可以执行插值,还为我们提供了组合字符串的灵活性,并将结构化文本转换为任何对象,而不仅仅是字符串。

模板表达式由三个组成部分组成:

模板处理器:Java 提供了两种用于执行字符串插值的模板处理器:STR 和 FMT

包含包装表达式的模板,如 {name}

点 (.) 字符

以下是一些关于如何将字符串模板与模板处理器一起使用的示例:

packagecom.mina.stringtemplates;

importstaticjava.util.FormatProcessor.FMT;

importjava.time.LocalDate;
importjava.time.format.DateTimeFormatter;

publicclassStringTemplateExamples{

publicstaticStringgreeting(StringfirstName,StringlastName){
returnSTR."Hello!Goodmorning{firstName}{lastName}";
}

publicstaticStringmultiplyWithArithmeticExpressions(inta,intb){
returnSTR."{a}times{b}={a*b}";
}

publicstaticStringmultiplyWithJavaExpression(inta,intb){
returnSTR."{a}times{b}={Math.multiplyExact(a,b)}";
}

//multiplicationwithfloatingpointnumbersroundedtotwodecimalplacesusingtheFMTtemplateprocessor
publicstaticStringmultiplyFloatingNumbers(doublea,doubleb){
returnFMT."%.2f{a}times%.2f{b}=%.2f{a*b}";
}

publicstaticStringgetErrorResponse(inthttpStatus,StringerrorMessage){
returnSTR."""
{
"httpStatus":{httpStatus},
"errorMessage":"{errorMessage}"
}""";
}

publicstaticStringgetCurrentDate(){
returnSTR."Today'sdate:{
LocalDate.now().format(
DateTimeFormatter.ofPattern("yyyy-MM-dd")
)}";
}
}

4 记录模式

记录模式匹配是一种在单个步骤中匹配记录类型并访问其组件的方法。

我们用它来测试一个值是否是记录类类型的实例,如果是,则对其组件值执行模式匹配。

下面的示例测试是否是具有记录模式transaction的记录实例TransactionTransaction(String type, double amount)

packagecom.mina.recordpattern;

publicclassRecordPatternExample{

//I'musing"_"forreadabilityhere,thiswon'tcompile
publicstaticStringgetTransactionType(Transactiontransaction){
returnswitch(transaction){
casenull->thrownewIllegalArgumentException("Transactioncannotbenull.");
caseTransaction(Stringtype,doubleamount)whentype.equals("Deposit")&&amount>0->"Deposit";
caseTransaction(Stringtype,_)whentype.equals("Withdrawal")->"Withdrawal";
default->"Unknowntransactiontype";
};
}

recordTransaction(Stringtype,doubleamount){

}
}

如果事务为空,会发生什么?你是对的——抛出了一个空指针异常。这也是Java 21中的情况,但是现在我们可以通过写case null->来显式地使用null case,这样可以避免NullPointerException。

保护模式:也可以保护特定情况。例如,我们使用when关键字来检查相等性。

5 switch 模式匹配

switch模式匹配在 Java 17 中作为预览功能引入,并在 Java 21 中永久保留。

语句switch将控制转移到多个语句或表达式之一,具体取决于其选择器表达式的值(可以是任何类型),并且case标签可以具有模式。

它检查其选择器表达式是否与模式匹配,与测试其选择器表达式是否完全等于常量相比,这更具可读性和灵活性。

packagecom.mina.switchpatternmatching;

importcom.mina.switchpatternmatching.SwitchPatternMatchingExample.Transaction.Deposit;
importcom.mina.switchpatternmatching.SwitchPatternMatchingExample.Transaction.Withdrawal;

publicclassSwitchPatternMatchingExample{

publicstaticStringgetTransactionType(Transactiontransaction){
returnswitch(transaction){
casenull:
thrownewIllegalArgumentException("Transactioncan'tbenull.");
caseDepositdepositwhendeposit.getAmount()>0://Guardedpatternwithwhenclause
yield"Deposit";
caseWithdrawalwithdrawal:
yield"Withdrawal";
default:
yield"Unknowntransactiontype";
};
}

sealedclassTransactionpermitsDeposit,Withdrawal{

privatedoubleamount;

publicTransaction(doubleamount){
this.amount=amount;
}

publicdoublegetAmount(){
returnamount;
}


finalclassWithdrawalextendsTransaction{

publicWithdrawal(doubleamount){
super(amount);
}
}

finalclassDepositextendsTransaction{

publicDeposit(doubleamount){
super(amount);
}
}
}
}

希望这篇文章可以帮助您更好地了解 Java 21 的新功能!


审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2966

    浏览量

    104700
  • 字符串
    +关注

    关注

    1

    文章

    578

    浏览量

    20505
  • 代码
    +关注

    关注

    30

    文章

    4779

    浏览量

    68516
  • 线程
    +关注

    关注

    0

    文章

    504

    浏览量

    19675

原文标题:Java 21 新特性的实践,确实很丝滑!

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    了解Java中的构造器

    C ++ 引入了构造器(constructor,也叫构造函数)的概念,它是在创建对象时被自动调用的特殊方法。 Java 也采用了构造器,并且还提供了个垃圾收集器(garbage collector),当不再使用内存资源的时候,垃圾收集器会自动将其释放。
    发表于 11-22 09:32 499次阅读

    PowerDesigner 10.0的新功能

    PowerDesigner 10.0的新功能Available February 9, 2004Business Process Simulation using
    发表于 06-27 17:01

    allegro 16.6 部分新功能 介绍

    本帖最后由 eric0921 于 2012-8-27 21:24 编辑 allegro 16.6部分新功能介绍
    发表于 08-27 21:23

    Altium Designer 20 新功能官方直播

    ,Altium大中华区技术经理将为大家带来Altium Designer 20的官方直播!现场、讲解演示新版本的全新功能及增强功能,还等什么,快复制链接报名吧!报名链接:https
    发表于 12-27 15:06

    21天学通JAVA2_袁国忠译

    21天学通Java2》包括4周的课程。第周介绍Java语言的基本知识,包括数据类型、变量、表达式、对象、数组、条件语句、循环、类、接口、包异常和线程等;第二周介绍
    发表于 12-06 10:38 0次下载
    <b class='flag-5'>21</b>天学通<b class='flag-5'>JAVA</b>2_袁国忠译

    Java学习路线教程之Java新手必须学习那21个技术点详细资料说明

    Java新手必学的21个技术点 以下为大家盘点作为Java新手必学的21个技术点,希望能够对想要学习编程,学习JAVA的人有些帮助! JN
    发表于 12-19 15:23 19次下载

    微软开始测试 21H1 的功能体验包功能 无需大版本更新即可体验

    Win10 21H1 是个小更新,它将在 2021 年上半年(5 月至 6 月)到来。21H1 几乎完全没有添加任何新功能,似乎仅在安全性和 “质量”方面有所改进,包括 Window
    的头像 发表于 02-24 14:29 1966次阅读

    苹果ios15新功能

     昨日,苹果WWDC21发表会如期举行,WWDC21中最让人值得关注的大概就是IOS15系统的发布。那么苹果此次发布的ios15系统有哪些新功能呢?下面我们起来看看!
    的头像 发表于 06-09 15:01 3288次阅读

    Java21版本的使用

      如果你是位苦逼的 Java 程序员,那么当你看到这张图的时候也许震惊的会跳起来! 但是我最大的感受是: 卧槽,怎么就Java 21了?!我还在用
    的头像 发表于 06-19 09:42 1911次阅读
    <b class='flag-5'>Java21</b>版本的使用

    了解 PCB 的有效导热系数

    了解 PCB 的有效导热系数
    的头像 发表于 11-24 15:48 1955次阅读
    <b class='flag-5'>一</b><b class='flag-5'>文</b><b class='flag-5'>了解</b> PCB 的有效导热系数

    了解刚柔结合制造过程

    了解刚柔结合制造过程
    的头像 发表于 12-04 16:22 769次阅读

    带你了解 DAC

    了解 DAC
    的头像 发表于 12-07 15:10 8761次阅读
    <b class='flag-5'>一</b><b class='flag-5'>文</b>带你<b class='flag-5'>了解</b> DAC

    言APP上线数字分身功能

    言APP近日上线了项令人兴奋的新功能——数字分身。这功能允许用户轻松创建自己的个性化虚
    的头像 发表于 02-04 10:32 1178次阅读

    浅谈Xpedition 2409版本的新功能

    在《创新不止|Xpedition 2409版本新功能揭秘(上)》中,我们了解了Xpedition 2409版本的部分改进部分。今天,我们继续看Xpedition 2409新版本给我
    的头像 发表于 10-31 15:33 679次阅读

    Java 23功能介绍

    功能。 跟上 Java 新版本的发布节奏可能很难,这意味着要解决连串的问题——更改是什么、为什么要更改以及如何使用全新和更新的功能。 在这篇博文中,我将介绍
    的头像 发表于 12-04 10:02 191次阅读
    <b class='flag-5'>Java</b> 23<b class='flag-5'>功能</b>介绍