jdk8到jdk11的新特性知识点总结(全了)

6 篇文章 1 订阅
2 篇文章 0 订阅

学习新特性之前配置高版本jdk时可能会采坑,小潘哥单独有一篇博客讲了下遇到的坑。


前言

为什么从java8讲起呢,其一 因为Java8是 Java 语言的一个重要版本,该版本于2014年3月发布,是自Java5以来最具革命性的版本,这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。其二java8和java11是长期支持版本(LTS)后续官方会长期维护。后续版本每半年出一个版本,最新版本java15在今年9月十五号已经推出。


提示:以下是本篇文章正文内容,下面案例可供参考

一、jdk8的新特性

java8的新特性还是比较多的如:函数式接口,Lambda表达式,方法引用,Stream接口, Optional类等等。

1.1函数式接口

    ..........  1.函数式接口主要指只包含一个抽象方法的接口,如:java.lang.Runnablejava.util.Comparator接口等。
    ..........  2.Java8提供@FunctionalInterface注解来定义函数式接口,若定义的接口不符合函数式的规范便会报错。
    ..........  3.Java8中增加了java.util.function包,该包包含了常用的函数式接口,具体如下:

在这里插入图片描述

 // 1.匿名内部类的语法格式: 父类/接口类型  引用变量名 = new 父类/接口类型(){ 方法的重写 };
     Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("我是既没有参数又没有返回值的方法!");
            }
        };
        runnable.run(); // 我是既没有参数又没有返回值的方法!

   Consumer consumer = new Consumer() {
            @Override
            public void accept(Object o) {
                System.out.println(o + "有参但没有返回值的方法就是我!");
            }
        };
        consumer.accept("友情提示:");
  Supplier supplier = new Supplier() {
            @Override
            public Object get() {
                return "无参有返回值!";
            }
        };
Function function = new Function() {
            @Override
            public Object apply(Object o) {
                return o;
            }
        };
        System.out.println(function.apply("有参有返回值的方法")); 

1.2Lambda表达式

… 1.Lambda 表达式是实例化函数式接口的重要方式,使用 Lambda 表达式可以使代码变的更加简洁紧凑。
… 2.lambda表达式:参数列表、箭头符号->和方法体组成,而方法体中可以是表达式,也可以是语句块。
… 3.语法格式:(参数列表) -> { 方法体; } - 其中()、参数类型、{} 以及return关键字 可以省略。

      //Runnable runnable1 = () -> { System.out.println("我是既没有参数又没有返回值的方法!"); };
   Runnable runnable1 = () -> System.out.println("我是既没有参数又没有返回值的方法!");
        runnable1.run();
  Consumer consumer1 = o -> System.out.println(o + "有参但没有返回值的方法就是我!");
        consumer1.accept("友情提示:");
  Supplier supplier1 = () -> "无参有返回值!";
        System.out.println(supplier1.get());
  Function function1 = o -> o;
        System.out.println(function1.apply("有参有返回值的方法"));

1.3 方法引用

… 1.方法引用主要指通过方法的名字来指向一个方法而不需要为方法引用提供方法体,该方法的调用交给函数式接口执行。
… 2.方法引用使用一对冒号 :: 将类或对象与方法名进行连接,通常使用方式如下:
… 对象的非静态方法引用 ObjectName :: MethodName
… 类的静态方法引用 ClassName :: StaticMethodName
… 类的非静态方法引用 ClassName :: MethodName
… 构造器的引用 ClassName :: new
… 数组的引用 TypeName[] :: new
方法引用是在特定场景下lambda表达式的一种简化表示,可以进一步简化代码的编写使代码更加紧凑简洁,从而减少冗余代码。

 // 使用lambda表达式对上述代码进行优化
        //list.stream().filter(person -> person.getAge() >= 18).forEach(person -> System.out.println(person));
        list.stream().filter(person -> person.getAge() >= 18).forEach(System.out::println);
```实现对集合中元素通过流跳过2个元素后再取3个元素后打印
        list.stream().skip(2).limit(3).forEach(System.out::println);

1.4Stream接口

(1)基本概念
java.util.stream.Stream接口是对集合功能的增强,可以对集合元素进行复杂的查找、过滤、筛选等操作。
Stream接口借助于Lambda 表达式极大的提高编程效率和程序可读性,同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势。
(2)使用步骤
创建Stream,通过一个数据源来获取一个流。
转换Stream,每次转换返回一个新的Stream对象。
对Stream进行聚合操作并产生结果。
(3)创建方式
方式一:通过调用集合的默认方法来获取流,如:default Stream stream()
方式二:通过数组工具类中的静态方法来获取流,如:static IntStream stream(int[] array)
方式三:通过Stream接口的静态方法来获取流,如:static Stream of(T… values)
方式四:通过Stream接口的静态方法来获取流,static Stream generate(Supplier<? extends T> s)
(4)中间操作
筛选与切片的常用方法如下:
在这里插入图片描述
映射的常用方法如下:
在这里插入图片描述

 		  // 11.实现将集合中所有元素的姓名映射出来并收集到集合中打印
list.stream().map(Person::getName).collect(Collectors.toList()).forEach(System.out::println);
               排序的常用方法如下:

在这里插入图片描述

list.stream().map(new Function<Person, Integer>() {
        @Override
        public Integer apply(Person person) {
            return person.getAge();
        }
    }).forEach(System.out::println);

    //list.stream().map(person -> person.getAge()).forEach(System.out::println);
    list.stream().map(Person::getAge).forEach(System.out::println);

    System.out.println("-------------------------------------------------------");
    // 7.实现集合中所有元素的自然排序并打印
    list.stream().sorted().forEach(System.out::println);

    System.out.println("-------------------------------------------------------");
    // 8.判断集合中是否没有元素的年龄是大于45岁的
    boolean b1 = list.stream().noneMatch(new Predicate<Person>() {
        @Override
        public boolean test(Person person) {
            return person.getAge() > 45;
        }
    });
    System.out.println("b1 = " + b1); // true

    b1 = list1.stream().noneMatch(person -> person.getAge() > 45);
    System.out.println("b1 = " + b1); // true

    System.out.println("-------------------------------------------------------");
    // 9.按照指定的比较器规则获取集合所有元素中的最大值
    Optional<Person> max = list.stream().max(new Comparator<Person>() {
        @Override
        public int compare(Person o1, Person o2) {
            return o1.getAge() - o2.getAge();
        }
    });
    System.out.println("按照年龄排序后的最大值是:" + max);

    max = list.stream().max((o1, o2) -> o1.getAge() - o2.getAge());
    System.out.println("按照年龄排序后的最大值是:" + max);

    System.out.println("-------------------------------------------------------");
    // 10.实现将集合中所有元素的年龄映射出来并进行累加后打印
    Optional<Integer> reduce = list.stream().map(Person::getAge).reduce(new BinaryOperator<Integer>() {
        @Override
        public Integer apply(Integer integer, Integer integer2) {
            return integer + integer2;
        }
    });
    System.out.println("最终所有年龄的累加和是:" + reduce); // 172

    //reduce = list.stream().map(Person::getAge).reduce(((integer, integer2) -> integer + integer2));
    reduce = list.stream().map(Person::getAge).reduce((Integer::sum));
    System.out.println("最终所有年龄的累加和是:" + reduce); // 172

    System.out.println("-------------------------------------------------------");
    // 11.实现将集合中所有元素的姓名映射出来并收集到集合中打印
    list.stream().map(Person::getName).collect(Collectors.toList()).forEach(System.out::println);

1.5Optional类

(1)基本概念
java.util.Optional类可以理解为一个简单的容器,其值可能是null或者不是null,代表一个值存在
或不存在。
该类的引入很好的解决空指针异常,不用显式进行空值检测。
(2)常用的方法
在这里插入图片描述

public static void main(String[] args) {

        //String str1 = "hello";
        String str1 = null;
        if (null != str1) {
            System.out.println("字符串的长度是:" + str1.length()); // 5  空指针异常
        } else {
            System.out.println("字符串为空,因此长度为0!");
        }

        System.out.println("----------------------------------------------------");
        // Java8中使用Optional类实现空值的处理
        // 1.将数据str1装到Optional对象代表的容器中
        Optional<String> optional = Optional.ofNullable(str1);
        // 2.建立映射关系  使用字符串的长度与字符串建立映射关系
        /*Optional<Integer> integer = optional.map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return s.length();
            }
        });*/
        //Optional<Integer> integer = optional.map(s -> s.length());
        Optional<Integer> integer = optional.map(String::length);
        // 3.若字符串为空则打印0,否则打印字符串的数值
        System.out.println("integer = " + integer); // Optional.empty
        System.out.println(integer.orElse(0)); // 0
    }

二、jdk9的新特性

Java9发布于2017年9月发布,带来了很多新特性,其中最主要的变化是模块化系统。模块就是代码和数据的封装体,模块的代码被组织成多个包,每个包中包含Java类和接口,模块的数据则包括资源文件和其他静态信息。

2.2 模块化的使用

(1)语法格式
在 module-info.java 文件中,我们可以用新的关键词module来声明一个模块,具体如下:
module 模块名称 {
}
(2)模块化的优势
减少内存的开销。可简化各种类库和大型应用的 开发和维护。安全性,可维护性,提高性能。

2.3 钻石操作符的使用升级

在Java9中允许在匿名内部类的使用中使用钻石操作符。

 public static void main(String[] args) {

        // 实现匿名内部类和钻石操作符的搭配使用
        //Comparator<Integer> comparator = new Comparator<Integer>() {
        Comparator<Integer> comparator = new Comparator<>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return 0;
            }
        };
    }

2.4 集合工厂方法

(1)基本概念
Java9的List、Set和Map集合中增加了静态工厂方法of实现不可变实例的创建。不可变体现在无法添加、修改和删除它们的元素。不允许添加null元素对象。
(2)实际意义
保证线程安全:在并发程序中既保证线程安全性,也大大增强了并发时的效率。被不可信的类库使用时会很安全。如果一个对象不需要支持修改操作,将会节省空间和时间的开销。可以当作一个常量来对待,并且这个对象在以后也不会被改变。

public static void main(String[] args) {

        // 创建List类型的不可变实例
        List<Integer> list = List.of(1, 2, 3, 4, 5);
        //list.add(6); // 编译ok,运行发生UnsupportedOperationException不支持此操作的异常
        System.out.println(list); // [1, 2, 3, 4, 5]

        Set<Integer> set = Set.of(6, 7, 8);
        //set.add(null);// 编译ok,运行发生UnsupportedOperationException不支持此操作的异常

        Map<Integer, String> map = Map.of(1, "one", 2, "two");
        //map.put(3, "three");// 编译ok,运行发生UnsupportedOperationException不支持此操作的异常
    }

2.5 InputStream的增强

InputStream类中提供了transferTo方法实现将数据直接传输到OutputStream中。

InputStream inputStream = null;
OutputStream outputStream = null;
inputStream = new FileInputStream("d:/a.txt");
outputStream = new FileOutputStream("d:/b.txt");
inputStream.transferTo(outputStream); // 实现数据的复制,底层是read和write方法的调用
outputStream.close();
inputStream.close();

三、jdk10的新特性

3.1 Java10的概述

Java10于2018年3月发布,改进的关键点包括一个本地类型推断、一个垃圾回收的增强。
Java10计划只是一个短期版本,因此公开更新将在六个月内结束,9月份发布的Java11将是Java的长期支持(LTS)版本,LTS版本的发布每三年发布一次。

3.2 局部变量类型推断

(1)基本概念
Java10可以使用var作为局部变量类型推断标识符,此符号仅适用于局部变量,增强for循环的索引,以及传统for循环的本地变量。它不能使用于方法形式参数,构造函数形式参数,方法返回类型,字段,catch形式参数或任何其他类型的变量声明。

 public static void main(String[] args) {

        // 由初始值可以推断出变量的类型,因此可以使用var取代
        //int num = 10;
        var num = 10;

        //List<Integer> list = new LinkedList<>();
        var list = new LinkedList<Integer>();
        list.add(10);

        for (var v : list) {
            System.out.println(v);
        }

        for (var i = 0; i < 10; i++) {}
    }

(2)实际意义

标识符var不是关键字,只是一个保留的类型名称。这意味着var用作变量,方法名或包名的代码不会受到影响,但var不能作为类或则接口的名字。避免了信息冗余。对齐了变量名。更容易阅读。

Java11的新特性

4.1 Java11的概述

Java11于2018年9月正式发布,这是 Java 大版本周期变化 后的第一个长期支持版本,非常值得关注。

4.2 简化的编译运行操作

在Java11中可以使用java命令一次性进行编译和运行操作。执行源文件中的第一个类必须包含主方法。不可以使用其它源文件中自定义的类。

4.3 String类新增方法

在这里插入图片描述

总结

以上就是今天要讲的内容,本文仅仅简单介绍了从java8到java11新特性的使用。当然更新的新特性还是比较多的不仅仅与此,java官方也在不断完善,今年9月15号java15已经出来了,足见选择了开发就是选择了终生学习。


好好学习,好好生活 ,迎娶白富美走上人生巅峰。欢迎 点赞 关注 收藏 评论。
  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值