史上最全jdk新特性总结,涵盖jdk8到jdk15!
前言
在本文中,我将描述自第8版以来Java最重要且对开发人员友好的功能。为什么会有这样的主意?在Web上,您可以找到许多文章,其中包含每种Java版本的新功能列表。但是,由于缺少文章,因此无法简要概述自第8版以来最重要的更改。好的,但是为什么是第8版?令人惊讶的是,它仍然是最常用的Java版本。即使我们已经到了Java 16发行版的前夕果。如您所见,超过46%的响应者仍在生产中使用Java 8。相比之下,只有不到10%的响应者使用Java 12或更高版本。
那接下来咋们从JDK8到JDK15,给大家介绍新的JDK提供给咋们的新特性!
JDK8
Lambda表达式
最直接作用就是减少代码,代码直接减少50%+,显得非常简洁
//使用java匿名内部类
Comparator<Integer> cpt = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
TreeSet<Integer> set = new TreeSet<>(cpt);
System.out.println("=========================");
//使用JDK8 lambda表达式
Comparator<Integer> cpt2 = (x,y) -> Integer.compare(x,y);
TreeSet<Integer> set2 = new TreeSet<>(cpt2);
// java7中 筛选产品为nike的
public List<Product> filterProductByColor(List<Product> list){
List<Product> prods = new ArrayList<>();
for (Product product : list){
if ("nike".equals(product.getName())){
prods.add(product);
}
}
return prods;
}
// 使用 lambda
public List<Product> filterProductByPrice(List<Product> list){
return list.stream().filter(p->"nike".equals(p.getName())).collect(Collectors.toList());
}
函数式接口
位于java.util.function包下,下面介绍最常用的几个
Predicate
接收一个值返回boolean
Predicate p = t->true;
Supplier
无接受参数返回一个值
Supplier<T> s = () -> new T();
Consumer
接受一个参数无返回值
Consumer<String> c = c -> System.out.println(s);
Function<T,R>
接受参数T 返回参数R
Function<Long,String> f = c -> String.valueof(c);
其他还有一些 BiFunction,BiConsumer,DoubleSupplier等大家有兴趣自己去阅读下源码
方法引用
静态引用:
格式:Class::static_method
List<String> list = Arrays.asList("a","b","c");
list.forEach(str -> System.out.print(str));
list.forEach(System.out::print);
构造器调用
构造器方法引用格式:Class::new,调用默认构造器
List<String> list = Arrays.asList("a","b","c");
List<Test> list.stream().map(Test::new).collect(Collectors.toList());
public class Test{
private final String desc;
public Test(String desc){
this.desc=desc;
}
}
方法调用
格式:instance::method
List<String> list = Arrays.asList("a","b","c");
Test test = new Test();
List<String> list.stream().map(test::toAdd).collect(Collectors.toList());
public class Test{
private final String desc;
public Test(String desc){
this.desc=desc;
}
public String toAdd(String desc){
return desc+"add";
}
}
Stream API
// 使用jdk1.8中的Stream API进行集合的操作
@Test
public void test(){
// 循环过滤元素
proList.stream()
.fliter((p) -> "红色".equals(p.getColor()))
.forEach(System.out::println);
// map处理元素然后再循环遍历
proList.stream()
.map(Product::getName)
.forEach(System.out::println);
// map处理元素转换成一个List
proList.stream()
.map(Product::getName)
.collect(Collectors.toList());
}
接口中的默认方法和静态方法
public interface ProtocolAdaptor {
ProtocolAdaptor INSTANCE = DynamicLoader.findFirst(ProtocolAdaptor.class).orElse(null);
default ProtocolAdaptor proxy() {
return (ProtocolAdaptor) Proxy.newProxyInstance(ProtocolAdaptor.class.getClassLoader(),
new Class[]{ProtocolAdaptor.class},
(proxy, method, args) -> intercept(method, args));
}
}
Optional
用于处理对象空指针异常:
public String getDesc(Test test){
return Optional.ofNullable(test)
.map(Test::getDesc).else("");
}
JDK9
收集工厂方法
借助Java 9的一项新功能,即集合工厂方法,您可以轻松地使用预定义的数据创建不可变的集合。您只需要在特定集合类型上使用of方法。
List<String> fruits = List.of("apple", "banana", "orange");
Map<Integer, String> numbers = Map.of(1, "one", 2,"two", 3, "three");
在Java 9之前,您可以使用Collections,但这绝对是一种更复杂的方法。
public List<String> fruits() {
List<String> fruitsTmp = new ArrayList<>();
fruitsTmp.add("apple");
fruitsTmp.add("banana");
fruitsTmp.add("orange");
return Collections.unmodifiableList(fruitsTmp);
}
public Map<Integer, String> numbers() {
Map<Integer, String> numbersTmp = new HashMap<>();
numbersTmp.put(1, "one");
numbersTmp.put(2, "two");
numbersTmp.put(3, "three");
return Collections.unmodifiableMap(numbersTmp);
}
同样,仅从ArrayList对象表创建即可使用Arrays.asList(...)method。
public List<String> fruitsFromArray() {
String[] fruitsArray = {"apple", "banana", "orange"};
return Arrays.asList(fruitsArray);
}
接口中的私有方法
从Java 8开始,您可以在接口内部使用公共默认方法。但是仅从Java 9开始,由于接口中的私有方法,您将能够充分利用此功能。
ublic interface ExampleInterface {
private void printMsg(String methodName) {
System.out.println("Calling interface");
System.out.println("Interface method: " + methodName);
}
default void method1() {
printMsg("method1");
}
default void method2() {
printMsg("method2");
}
}
JDK10
从Java 9和Java 10开始,有几种用于Optional的有用方法。其中最有趣的两个是orElseThrow和ifPresentOrElse。如果没有值,则使用该orElseThrow方法抛出NoSuchElementException。否则,它返回一个值。
public Person getPersonById(Long id) {
Optional<Person> personOpt = repository.findById(id);
return personOpt.orElseThrow();
}
因此,您可以避免将带参数的if语句与isPresentmethod一起使用。
public Person getPersonByIdOldWay(Long id) {
Optional<Person> personOpt = repository.findById(id);
if (personOpt.isPresent())
return personOpt.get();
else
throw new NoSuchElementException();
}
第二种有趣的方法是ifPresentOrElse。如果存在一个值,它将使用该值执行给定的操作。否则,它将执行给定的基于空的操作。
public void printPersonById(Long id) {
Optional<Person> personOpt = repository.findById(id);
personOpt.ifPresentOrElse(
System.out::println,
() -> System.out.println("Person not found")
);
}
在Java 8中,我们可以if-else直接与isPresent方法一起使用。
public void printPersonByIdOldWay(Long id) {
Optional<Person> personOpt = repository.findById(id);
if (personOpt.isPresent())
System.out.println(personOpt.get());
else
System.out.println("Person not found");
}
JDK 10 && JDK 11
从Java 10开始,您可以声明没有其类型的局部变量。您只需要定义var关键字而不是类型。从Java 11开始,您还可以将其与lambda表达式一起使用,如下所示。
public String sumOfString() {
BiFunction<String, String, String> func = (var x, var y) -> x + y;
return func.apply("abc", "efg");
}
JDK 12
使用Switch表达式,您可以定义多个case标签并使用箭头返回值。此功能自JDK 12起可用。它使Switch表达式真正更易于访问。
public String newMultiSwitch(int day) {
return switch (day) {
case 1, 2, 3, 4, 5 -> "workday";
case 6, 7 -> "weekend";
default -> "invalid";
};
}
对于低于12的Java,相同的示例要复杂得多。
public String oldMultiSwitch(int day) {
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
return "workday";
case 6:
case 7:
return "weekend";
default:
return "invalid";
}
}
JDK 13
文本块是多行字符串文字,它避免使用转义序列,并以可预测的方式自动设置字符串格式。它还使开发人员可以控制字符串的格式。从Java 13开始,文本块可用作预览功能。它们以三个双引号(""")开头。让我们看看我们如何轻松地创建和格式化JSON消息。
public String getNewPrettyPrintJson() {
return """
{
"firstName": "Piotr",
"lastName": "Mińkowski"
}
""";
}
创建Java 13之前的相同JSON字符串要复杂得多。
public String getOldPrettyPrintJson() {
return "{\n" +
" \"firstName\": \"Piotr\",\n" +
" \"lastName\": \"Mińkowski\"\n" +
"}";
}
JDK14
使用Records,您可以定义不可变的纯数据类(仅限getter)。它会自动创建toString,equals和hashCode方法。实际上,您只需要定义如下所示的字段即可。
public record Person(String name, int age) {}
具有类似功能的类如record包含字段,构造函数,getter和实施toString,equals以及hashCode方法。
public class PersonOld {
private final String name;
private final int age;
public PersonOld(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PersonOld personOld = (PersonOld) o;
return age == personOld.age && name.equals(personOld.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "PersonOld{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
JDK15
使用密封类功能,您可以限制超类的使用。使用new关键字,sealed您可以定义哪些其他类或接口可以扩展或实现当前类。
public abstract sealed class Pet permits Cat, Dog {}
允许的子类必须定义一个修饰符。如果您不想允许任何其他扩展名,则需要使用final关键字。
public final class Cat extends Pet {}
另一方面,您可以打开扩展类。在这种情况下,应使用non-sealed修饰符。
public non-sealed class Dog extends Pet {}
当然,下面的可见声明是不允许的。
public final class Tiger extends Pet {}
END
原创整理不容易,欢迎大家关注公众号!阅读更多好文!
欢迎关注公众号!
公众号回复:入群
,扫码加入我们交流群!
史上最全jdk新特性总结,涵盖jdk8到jdk15!的更多相关文章
- 这可能是史上最好的 Java8 新特性 Stream 流教程
本文翻译自 https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ 作者: @Winterbe 欢迎关注个人微信公众 ...
- 史上最全的maven pom.xml文件教程详解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 史上最全阿里 Java 面试题总结
以下为大家整理了阿里巴巴史上最全的 Java 面试题,涉及大量 Java 面试知识点和相关试题. JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节. String类能被继承吗,为什么 ...
- 史上最全的maven的pom.xml文件详解(转载)
此文出处:史上最全的maven的pom.xml文件详解——阿豪聊干货 <project xmlns="http://maven.apache.org/POM/4.0.0" x ...
- 史上最全的spark面试题——持续更新中
史上最全的spark面试题——持续更新中 2018年09月09日 16:34:10 为了九亿少女的期待 阅读数 13696更多 分类专栏: Spark 面试题 版权声明:本文为博主原创文章,遵循C ...
- Redis分布式锁 (图解-秒懂-史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- Java基础面试题(史上最全、持续更新、吐血推荐)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- sentinel (史上最全+入门教程)
文章很长,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈 为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 < Java 高并发 三部曲 > 面试必备 + 大厂 ...
- spring + spring mvc + tomcat 面试题(史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
随机推荐
- 人物传记JULLIAN MURPHY:投资哪家强,区块链必然>股票+房地产
今年上半年在金融股市出现巨大波动的时候,星盟的项目审核经理JULLIAN MURPHY发现了一个有趣的现象:各种熔断和暴跌的背后,特斯拉的股票却从去年年末开始至今已经暴涨了12倍,即便中途有所回落,但 ...
- PAA子公司在印度印度成立
近日PAA房产又有大动作啦!在一片期待中,印度分公司正式成立!这是集团继泰国.越南.韩国.上海.成都.中国香港.中国台湾等分公司成立之后的又一扛鼎力作,更是PAA集团全球化战略布局的重要举措. 印度分 ...
- 图像仿射变换——MatLab代码实现
这里先说一下我们的目的,最近在用Pix2Pix 做一个项目的时候,遇到了成对图像质量差,存在着特征不能对齐的问题,即A图与B图是一组成对图像,我们想要将A 图中的物体转化为B 图中的物体,但这个物体在 ...
- 【ZeyFraのJavaEE开发小知识01】@DateTimeFomat和@JsonFormat
@DateTimeFormat 所在包:org.springframework.format.annotation.DateTimeFormat springframework的注解,一般用来对Dat ...
- 《C++ Primer》笔记 第1章 开始
输出运算符<< 的计算结果就是其左侧运算对象 std::endl 结束当前行,并将与设备关联的缓冲区中的内容刷到设备中. 程序员常常在调试时添加打印语句.这类语句应该保证"一直& ...
- 解决appium点击软键盘上的搜索按钮
在执行appium自动化测试的时候,需要点击软件盘上的搜索按钮. 具体操作步骤如下: 前提:需要事先安装搜狗输入法 1.唤醒软件盘,可以封装到一个类里,用到的时候随时调用. import os#调起s ...
- Webpack 基石 tapable 揭秘
Webpack 基于 tapable 构建了其复杂庞大的流程管理系统,基于 tapable 的架构不仅解耦了流程节点和流程的具体实现,还保证了 Webpack 强大的扩展能力:学习掌握tapable, ...
- Flink实时计算topN热榜
TopN的常见应用场景,最热商品购买量,最高人气作者的阅读量等等. 1. 用到的知识点 Flink创建kafka数据源: 基于 EventTime 处理,如何指定 Watermark: Flink中的 ...
- 三分钟教你提升应用推送的ROI
推送是App应用性价比最高也是最直接的营销运营手段,其细节颇多,非常考验运营人员的功力,本文将从ROI角度来分析怎么提升营销类推送的收益.(非IM类.系统类等功能服务型推送) 以一个日活100万的应用 ...
- 常用开发库 - 告別BeanUtils拷贝,MapStruct工具库最全详解
常用开发库 - MapStruct工具库详解 MapStruct是一款非常实用Java工具,主要用于解决对象之间的拷贝问题,比如PO/DTO/VO/QueryParam之间的转换问题.区别于BeanU ...