• 【Java】JDK11特性概览


    目录

    一. 字符串 API增强

    1.1 isBlank()

    1.2 lines()

    1.3 repeat(n)

    1.4 strip()

    二. 文件中读写字符串

    2.1 从文件中读取和写入字符串内容

    三. 集合转对应类型的数组

    3.1 toArray

    3.2 Predicate not

    四、var局部变量类型推断

    4.1  var 修饰 Lambda

    五. 数据流 Streams

    5.1 Stream.ofNullable 

    5.2 dropWhile

    5.3 takeWhile

    5.4 Optionals

    六、垃圾收集器

    6.1 Epsilon

    6.2 ZGC


     

    JDK 11是自JDK 8以来的又一个LTS版本,是目前全球使用最多的LTS版本之一。下边看一下JDK 11的新特性

    一. 字符串 API增强

    在Java 11中,针对String的操作进一步得到加强。避免在很常见的场景中引入额外的、复杂的API

    1.1 isBlank()

    用来判断字符串是不是空字符"“或者trim()之后(” ")为空字符:

    1.  String blankStr = "    ";
    2.  // true
    3.  boolean trueVal = blankStr.isBlank();


    1.2 lines()

    将一个字符串按照行终止符(换行符\n或者回车符\r)进行分割,并将分割为Stream流:

    1. String newStr = "Hello Java 11 \n aaaaa \r 2021-09-28";
    2. Stream lines = newStr.lines();
    3. lines.forEach(System.out::println);

    输出结果为:

    Hello Java 11

     aaaaa

     2021-09-28

    1.3 repeat(n)

    按照给定的次数重复串联字符串的内容:

    1. String str = "JDK11";
    2. // 空字符
    3. String empty = str.repeat(0);
    4. // JDK11
    5. String repeatOne = str.repeat(1);
    6. // JDK11JDK11
    7. String repeatTwo = str.repeat(2);

    1.4 strip()

    去除字符串前后的“全角和半角”空白字符:

    1. String str = "JDK11\u3000";
    2. // str = 6
    3. System.out.println("str = " + str.length());
    4. // trim = 6
    5. System.out.println("trim = " + str.trim().length());
    6. // strip = 5
    7. System.out.println("strip = " + str.strip().length());

    二. 文件中读写字符串

    2.1 从文件中读取和写入字符串内容

    Java 11中可以更轻松地从文件中读取和写入字符串内容了,可以通过Files工具类提供的新的静态方法:

    readString

    writeString

    分别进行读写文件的字符串内容

    放在之前很麻烦了,特别是对IO流不熟悉的同学来说。现在简单几行就搞定了:

    1. String dir= "d://test/hello.txt";
    2. // 写入文件
    3. Path path = Files.writeString(Path.of(dir), "hello jdk 11");
    4. // 读取文件
    5. String fileContent = Files.readString(path);
    6. // hello jdk 11
    7. System.err.println(fileContent);

    三. 集合转对应类型的数组

    3.1 toArray

    之前想集合转对应的数组很麻烦,要么用迭代;要么用Stream流,现在你可以这样:

    1. List sampleList = Arrays.asList("张三", "java 11");
    2. // array = {"张三", "java 11"};
    3. String[] array = sampleList.toArray(String[]::new);

    3.2 Predicate not

    java.util.function.Predicate是我们很常用的断言谓词函数。在以前取反我们得借助于!符号,在Java 11中可以借助于其静态方法not来实现,这样语义就更加清晰了:

    1. List sampleList = Arrays.asList("test", "JDK 11","jack");
    2. // [jack]
    3. List result = sampleList.stream()
    4. // 过滤以j开头的字符串
    5. .filter(s -> s.startsWith("j"))
    6. // 同时不包含11的字符串
    7. .filter(Predicate.not(s -> s.contains("11")))
    8. .collect(Collectors.toList());

    四、var局部变量类型推断

    局部变量类型推断就是左边的类型直接使用 var 定义,而不用写具体的类型,编译器能根据右边的表达式自动推断类型,

    var 语法 : 局部变量的类型推断

    注意 :

    1 var a; 这样不可以, 因为无法推断

    类的属性的数据类型不可以使用var.

    Java 10之前,你需要这样声明一个String对象。

    使用var的有点:在使用lambda表达式时给参数加上注解

    (@Deprecated var x, @Nullable var y) -> x.process(y);
     

    4.1  var 修饰 Lambda

    var可以用于修饰Lambda局部变量

    在Java 10中引入的var来进行类型推断。在Java 10中它不能用于修饰Lambda表达式的入参,其实对于一个Lambda表达式来说它入参的类型其实是可以根据上下文推断出来的。

    拿上面的例子来说,s -> s.startsWith(“j”)中的s肯定是字符串类型,因此在Java 11中var可以用于修饰Lambda局部变量


    如果不声明var,就没有办法为输入参数添加@NotNull注解

    1. List sampleList = Arrays.asList("张三", "java 11","jack");
    2. List result = sampleList.stream()
    3. // 过滤以j开头的字符串
    4. .filter((@NotNull var s) -> s.startsWith("j"))
    5. // 同时不包含11的字符串
    6. .filter(Predicate.not((@NotNull var s) -> s.contains("11")))
    7. .collect(Collectors.toList());

    五. 数据流 Streams

    流是在 Java 8 中引入的,现在增加了三个新方法。

    1,Stream.ofNullable 

    2,dropWhile

    3, takeWhile

    5.1 Stream.ofNullable 

    从单个元素构造流

    1. Stream.ofNullable(null)
    2. .count() // 0

    5.2 dropWhile

    方法都接受一个谓词来决定从流中放弃哪些元素

    1. Stream.of(1, 2, 3, 2, 1)
    2. .dropWhile(n -> n < 3)
    3. .collect(Collectors.toList()); // [3, 2, 1]

    5.3 takeWhile

    方法都接受一个谓词来决定从流中选用哪些元素

    1. Stream.of(1, 2, 3, 2, 1)
    2. .takeWhile(n -> n < 3)
    3. .collect(Collectors.toList()); // [1, 2]

    5.4 Optionals

    Optionals 增加了非常方便的新方法,例如,现在可以简单地将 Optionals 转换为流,或者提供另一个 Optionals 作为空 Optionals 的回调

    1. Optional.of("foo").orElseThrow(); // foo
    2. Optional.of("foo").stream().count(); // 1
    3. Optional.ofNullable(null)
    4. .or(() -> Optional.of("fallback"))
    5. .get();

    六、垃圾收集器

    6.1 Epsilon

    JDK 11上对这个特性的描述是:开发一个处理内存分配但不实现任何实际内存回收机制的GC,一旦可用堆内存用完,JVM就会退出

    它的主要用途有以下几个方面:

    • 性能测试(它可以帮助过滤掉GC引起的性能假象)
    • 内存压力测试
    • 非常短的JOB任务
    • VM接口测试

    可以来尝试着使用一下它,首先编写一段程序:

    1. public class EpsilonTest {
    2. public static void main(String[] args) throws Exception {
    3. var list = new ArrayList<>();
    4. boolean flag = true;
    5. int count = 0;
    6. while (flag) {
    7. list.add(new Garbage());
    8. if (count++ == 500) {
    9. list.clear();
    10. }
    11. }
    12. }
    13. }
    14. class Garbage {
    15. private double d1 = 1;
    16. private double d2 = 2;
    17. /**
    18. * GC在清除本对象时会调用该方法
    19. */
    20. @Override
    21. protected void finalize() throws Throwable {
    22. System.out.println(this + " collecting");
    23. }
    24. }

    这是一个无限循环的程序,循环体不断创建Garbage对象并放入集合,当循环次数达到500时将集合清空,此时的500个对象均为垃圾,会被GC清理,清理时调用finalize()方法打印信息。运行这段程序,结果如下:

    1. ...
    2. com.itcast.Garbage@1e9c634c collecting
    3. java.lang.OutOfMemoryError: Java heap space
    4. at com.itcast.EpsilonTest.main(EpsilonTest.java:11)
    5. com.itcast.Garbage@1174213e collecting
    6. com.itcast.Garbage@2029a4b8 collecting
    7. ...

     当程序执行到某一刻时,内存溢出,程序终止。现在来使用一下Epsilon,启动参数: UnlockExperimentalVMOptions:解锁隐藏的虚拟机参数。

    -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xms100m -Xmx100m
    

    运行程序后,结果如下:

    1. 程序开始
    2. Terminating due to java.lang.OutOfMemoryError: Java heap space

    会发现,控制台只输出了这么一句,说明被清除的集合中的对象并没有被回收而且内存溢出的速度也非常快

    这说明该GC是并不会回收垃圾,它提供完全被动的GC实现,具有有限的分配限制和尽可能低的延迟开销,但代价是内存占用和内存吞吐量

    6.2 ZGC

    据说这是JDK11最为瞩目的特性,没有之一,是最重磅的升级。

    ZGC的优势:

    1. GC暂停时间不会超过10毫秒
    2. 既能处理几百兆的小堆,也能处理几个T的大堆
    3. 和G1相比,应用吞吐能力不会下降超过15%
    4. 为未来的GC功能和利用colord指针以及Load barriers优化奠定了基础


    ZGC是一个并发、基于region、压缩型的垃圾收集器,只有root扫描阶段会STW(strop the world,停止所有线程),因此ZGC的停顿时间不会随着堆的增长和存活对象的增长而变长。

    用法:-XX:UnlockExperimentalVMOptions -XX:+UseZGC
     

  • 相关阅读:
    JDBC学习笔记
    CSDN参加欧洲最大开源盛会KubeCon,与全球开发者共促开源生态发展
    mac idea 解决0% classes 0% lines covered不显示,非快捷键办法
    Leetcode6254-划分技能点相等的团队
    java17 新特性(实用)
    SpringBoot运行原理
    【python】求先序排列
    <select>表单元素
    ABC344 A-E题解
    新手零基础自学Python,安装并配置环境+教程
  • 原文地址:https://blog.csdn.net/weixin_36755535/article/details/126951465