前言

在本文中,我将描述自第8版以来Java最重要且对开发人员友好的功能。为什么会有这样的主意?在Web上,您可以找到许多文章,其中包含每种Java版本的新功能列表。但是,由于缺少文章,因此无法简要概述自第8版以来最重要的更改。好的,但是为什么是第8版?令人惊讶的是,它仍然是最常用的Java版本。即使我们已经到了Java 16发行版的前夕。如您所见,超过46%的响应者仍在生产中使用Java 8。相比之下,只有不到10%的响应者使用Java 12或更高版本。

java版本使用占比

那接下来咋们从JDK8到JDK15,给大家介绍新的JDK提供给咋们的新特性!

 

JDK8

  1. Lambda表达式

最直接作用就是减少代码,代码直接减少50%+,显得非常简洁

 //使用java匿名内部类Comparator<Integer> cpt = new Comparator<Integer>() {@Overridepublic 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());  }
  1. 函数式接口

位于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等大家有兴趣自己去阅读下源码

  1. 方法引用

  • 静态引用:格式: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";}
}
  1. 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处理元素转换成一个ListproList.stream().map(Product::getName).collect(Collectors.toList());
}
  1. 接口中的默认方法和静态方法

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));}
}
  1. 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();elsethrow 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());elseSystem.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;}@Overridepublic 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);}@Overridepublic int hashCode() {return Objects.hash(name, age);}@Overridepublic 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 {}

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

史上最全jdk版本新特性大全相关推荐

  1. 史上最全Java 8新特性总结,助你在工作事半功倍

    1.Lambda表达式 1.初体验 目标:了解使用匿名内部类存在的问题,体验Lambda 匿名内部类存在的问题:当需要启动一个线程去完成任务时,通常会通过Runnable 接口来定义任务内容,并使用T ...

  2. 史上最全电子产品接口知识大全(含实物图40种,收藏)

    史上最全电子产品接口知识大全(含实物图40种,收藏) 2017-07-31 EDN电子技术设计 1.IDE接口(一种硬盘接口) IDE的英文全称为"Integrated Drive Elec ...

  3. 史上很全的注册表修改大全

    史上很全的注册表修改大全 请使用 Ctrl+F 键来查找你想要的 不想别人使用你电脑的某些功能,或是在网吧想使用某些功能,或是让自己的电脑速度更快 怎么办 如果你有点注册表的知识就OK拉 没有多深奥 ...

  4. 对外汉语语料库有哪些_[转载]史上最全最新的语料库资源大全【对外汉语教学研究工具】...

    果断收藏!分享给好友!史上最全最新的语料库资源大全.本文持续更新,欢迎订阅期刊<对外汉语北京>以便获得最新通知! [期刊] International Journal of Corpus ...

  5. 史上最全WindowsMac系统各种快捷键大全(1000余个)

    史上最全Windows&Mac系统各种快捷键大全(1000余个) Windows NT6.2+专用快捷键: Windows+ F 搜索文件或文件夹  Windows+ 空格键 切换语言或输入法 ...

  6. 深度干货:史上最全的市场推广渠道大全(附攻略和技巧)

    我相信,这或许是史上最全的推广渠道文章.如果你的企业正需要扩张,不妨看一看,或能有所帮助. 在开始推广之前,有一件重要的事要做,那就是市场定位,因为在后面的推广策略,渠道选择,营销诉求等都要围绕这个来 ...

  7. JDK版本新特性介绍JDK1.6

    JDK1.6新特性介绍 1. Desktop类和SystemTray类 在JDK6中 ,AWT新增加了两个类:Desktop和SystemTray. 前者可以用来打开系统默认浏览器浏览指定的URL,打 ...

  8. 史上最全的CSS基础知识大全!

    文章目录 CSS的发展历程 CSS 网页的美容师 CSS初识 CSS样式规则 CSS字体样式属性 font-size:字号大小 font-family:字体 font-weight:字体粗细 font ...

  9. 史上最全的android studio 插件大全整理

    现在Android的开发者基本上都使用Android Studio进行开发(如果你还在使用eclipse那也行,毕竟你乐意怎么样都行).使用好Android Studio插件能大量的减少我们的工作量. ...

最新文章

  1. C#中的BackgroundWorker控件
  2. 1.2.2 OSI参考模型
  3. 错误602,未能在sysindexes中找到数据库 的解决办法
  4. Numpy中array和matrix转换
  5. 使用 Palette 让你的 UI 色彩与内容更贴合
  6. 边学习新技术边工作的重要性
  7. 自动化日志收集及分析在支付宝 App 内的演进
  8. NVIDIA向交通运输行业开源其自动驾驶汽车深度神经网络
  9. linux下安装apache与php;Apache+PHP+MySQL配置攻略
  10. 银行客户交易行为预测:如何降低内存的使用量
  11. 如何在应用程序中隐藏2021款MacBook刘海?
  12. dubbo 学习资料
  13. iOS:定制自适应大小的透明吐司弹框
  14. 学习小甲鱼Python入门(二)习题笔记-列表
  15. 跳一跳python源码下载_微信跳一跳游戏python脚本
  16. 海南楼市充斥着传说 投机者必将自食其果
  17. 如何解决中小企业融资难问题
  18. pc端编码表必须为gbk才能正常启动软件_【干货】请收下这份非常完整的PCIE4.0 发送端测试SOP...
  19. 崩坏3九游服务器稳定吗,为什么崩坏三萌新入坑推荐选择官服而非渠道服,盘点几个必要的理由...
  20. 论文阅读|两人零和马尔可夫博弈的在线极大极小Q网络学习《Online Minimax Q Network Learning for TZMGs》

热门文章

  1. mysql large_【转】mysql对large page的支持
  2. native react 常用指令_React Native 常用的 15 个库
  3. QT 线程池 + TCP 小试(三)实现最终功能
  4. 后端返回页面ajax的处理
  5. Nmap流量特征修改(NTA、IDS、IPS、流量审计)
  6. KVM 创建虚拟机时,--os-variant参数这样填写
  7. https加密过程(详细)
  8. Qt:Qt实现飞秋拦截助手—ARP攻击
  9. mysql基本介绍和优化技巧
  10. Red and Black (找到一个标记一个)