• Java8新特性


    JDK8新特新

    第一章 java8的优势

    • 速度更快
    • 代码更少(增加了新语法lambda式)
    • 强大的StreamAPI
    • 便于并行
    • 最大化减少空指针异常Optional
    • Nashorn引擎,允许在JVM上运行JS应用

    第2章 lambda表达式

    2.1 简介

    Lambda 表达式:在java8语言引入的一种心得语法元素和操作符,这个操作符为 “->” ,该操作符被统称为Lambda操作符或者箭头操作符。它将Lambda分为两个部分:

    *     -> :lambda操作符,也称箭头操作符
    *     -> 左边是  lambda形参列表 (接口中抽象方法的形参列表)
    *     -> 右边是  lambda体 (重写的抽象方法的方法体)
    
    • 1
    • 2
    • 3

    2.2 使用语法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cd8ynsgJ-1663430283628)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20220916113400854.png)]

    在这里插入图片描述

    Lambda 表达式的本质:作为接口的实例

    第3章 函数式(Funtional)接口

    3.1 基本介绍

    如果一个接口中,只声明一个抽象方法,则此接口就称为函数式接口

    1)可以通过Lambda表达式来创建该接口的对象,(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明

    2)我们可以在一个接口上使用@FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口

    package com.ldm.java8;
    
    /**
     * @author 梁东明
     * 2022/9/16
     * 人生建议:看不懂的方法或者类记得CTRL + 点击 看看源码或者注解
     * 点击setting在Editor 的File and Code Templates 修改
     */
    @FunctionalInterface
    public interface MyInterface {
        void ldm();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.2 详细介绍

    1)Java从诞生起就一直倡导“万物皆可对象”,在Java里面向对象(OOP)编程是一切,但是随着python、Scala等语言的兴起和挑战,Java不得不作出调整以便支持更加广泛的技术要求,也即Java不但可以支持OOP还可以支持OOF(面向函数编程)

    2)在函数式编程语言中,函数被当作一等公民对待,在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数,但是在Java8中,有所不同。在Java8注解,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型—函数式接口

    3)简单地说:在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也即是说,只要一个对象是函数式接口的实例 ,那么该对象就可以用Lambda表达式来表达

    3.3 四大函数式接口核心

    在这里插入图片描述

    package com.ldm.java8.Lambda;
    
    import org.junit.jupiter.api.Test;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Consumer;
    import java.util.function.Predicate;
    
    /**
     * @author 梁东明
     * 2022/9/16
     * 人生建议:看不懂的方法或者类记得CTRL + 点击 看看源码或者注解
     * 点击setting在Editor 的File and Code Templates 修改
     */
    public class LambdaTest02 {
        @Test
        public void test01(){
            SpendMoney(500, new Consumer<Double>() {
                @Override
                public void accept(Double money) {
                    System.out.println("去看电影花费了" + money+"元" );
                }
            });
            System.out.println("使用Lambda表达式");
            SpendMoney(500, money -> System.out.println("去看电影花费了" + money+"元" ));
        }
    
        public static void SpendMoney(double money, Consumer<Double> con){
            con.accept(money);
        }
    
        @Test
        public void test02(){
            List<String> list = Arrays.asList("北京","上海","广州","深圳","东莞");
            List<String> filter1 = filterString(list, new Predicate<String>() {
                @Override
                public boolean test(String s) {
                    return s.contains("京");
    
                }
            });
            System.out.println("filterString = " + filter1);
            System.out.println("====使用Lambda表达式====");
            List<String> filter2 = filterString(list, (s -> s.contains("京")));
            System.out.println("filter2 = " + filter2);
    
        }
    
    
        /**
         * 过滤字符串
         * 根据给定的规则,过滤集合中的字符串,此规则由predicate的方法规定
         *
         * @param list      列表
         * @param predicate 函数式接口的一种
         */
        public static List<String> filterString(List<String> list, Predicate<String> predicate){
    
            ArrayList<String> filterString = new ArrayList<>();
            for (String s : list) {
                if (predicate.test(s)){
                    filterString.add(s);
                }
            }
            return filterString;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    其他函数式接口

    我就不一一实现了
    在这里插入图片描述

    第3章 方法引用

    3.1 基本介绍

    方法引用(method References)

    • 当腰传递给Lambda体的操作,已经有实现的方法,可以使用方法引用
    • 方法引用可以看作是Lambda表达式深层次的表达,换而言之,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法
    • 要求: 实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
    • 格式: 使用操作符 “ :: ” 将类(或对象)与方法名分隔开来
    • 主要如下三种使用情况
      • 对象 :: 实例方法名
      • 类 ::静态方法名
      • 类 :: 实例方法名
    package com.ldm.java8.MethodReferences;
    
    import org.junit.jupiter.api.Test;
    import org.omg.PortableInterceptor.INACTIVE;
    
    import java.io.PrintStream;
    import java.util.Comparator;
    import java.util.function.Consumer;
    
    /**
     * @author 梁东明
     * 2022/9/16
     * 人生建议:看不懂的方法或者类记得CTRL + 点击 看看源码或者注解
     * 点击setting在Editor 的File and Code Templates 修改
     *
     * 方法引用举例在·
     */
    public class test {
        //对象 :: 实例方法名
        @Test
        public void test01(){
            Consumer<String> con1 = str -> System.out.println(str);
            con1.accept("北京");
            System.out.println("====使用方法引用====");
            PrintStream ps = System.out;
            Consumer<String> con2 = ps ::println;
            con2.accept("beijing");
        }
        //类 :: 静态方法
        @Test
        public void test02(){
            Comparator<Integer> c1 = (t1,t2) -> Integer.compare(t1,t2);
            int compare = c1.compare(12, 34);
            System.out.println("compare = " + compare);
            System.out.println("=====方法引用=====");
            Comparator<Integer> c2 = Integer ::compare;
            int compare1 = c2.compare(12, 34);
            System.out.println("compare1 = " + compare1);
        }
        //类 :: 实例方法名
        @Test
        public void test03(){
            Comparator<String> c1 = (t1,t2) -> t1.compareTo(t2);
            int compare = c1.compare("adb", "abd");
            System.out.println(compare);
            System.out.println("====使用方法引用=====");
            Comparator<String> c2 = String::compareTo;
            int compare1 = c2.compare("adb", "abd");
            System.out.println(compare1);
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    第4章StreamAPI

    4.1 概述

    • Java8中最为重要的改变。第一个是Lambda表达式,另外一个则是StreamAPI
    • StreamAPI(java.util.stream) 把真正的函数式编程风格引入到Java中,这是目前位置对Java库类最好的补充,因为StreamAPI可以极大提供Java程序员的生产力,让程序员写出更高效、干净、简介的代码
    • Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和隐射数据等操作。使用StreamAPI对集合数据进行操作,就类似于使用SQL执行的数据库查询也可以使用StreamAPI来并行执行操作,简而言之:StreamAPI提供了一种高效且易于使用的处理数据的方式

    为什么要使用StreamAPI

    • 实际开发中,项目中多数数据源都来自Mysql,Oracle等。但现在数据源可以更多了,有MongDB,Redis等,而这些NoSQL的数据就需要Java层面去处理
    • Stream和Collection集合的区别:Collection是一种静态的内存数据结构,而Stream是有关计算的,前者是主要面向内存,存储在内存中,后者主要面向CPU,通过CPU实现计算

    4.2 什么是Stream

    • Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列
    • ”集合讲的是数据,Stream讲的是计算“

    注意:

    ①Stream自己不会存储元素

    ②Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream

    ③Stream操作时延迟执行的,这意味着他们呢会等到需要结果的时候才执行

    4.2Stream操作的三个步骤

    • 1-创建Stream

    一个数据源(如:集合、数组),获取一个流

    • 2-中间操作

    一个中间操作链,对数据源的数据进行处理

    • 3-终止操作(终端操作)

    一旦执行终止操作,就执行中间操作链,并产生结果,之后,就不会再被使用

    在这里插入图片描述

    4.2.1 Stream的创建

    创建Stream方式1:通过集合

    Java8中的Collection接口被扩展,提供了两个获取流的方法

    • default Stream stream() : 返回一个顺序流
    • default Stream parallelStream() : 返回一个并行流

    创建Stream的方式二: 通过数组

    java8中的Arrays的静态方法stream() 可以获取数组流:

    • static stream stream(T[] array):返回一个流

    重载形式,能够处理对应基本类型的数组

    • public static IntStream stream(int[] array)
    • public static LongStream stream(long[] array)
    • public static DoubleStream stream(double[] array)

    创建Stream的方式三:通过stream的of()

    可以调用Stream类静态方法of(),通过显示值创建一个流,它可以接收任意数量的参数

    • public static Stream of(T… vaulues) : 返回一个流

    创建Stream的方式四:创建无限流

    可以使用静态方法Stream.iterate() 和Stream.generate(),创建无限流

    • 迭代

    public static Stream iterate(final T seed,final UnaryOperator f)

    • 生成

    public static Stream generate(Supplier s)

    4.2.2 Stream的中间操作

    1、筛选与切片

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HZtja5kv-1663430283631)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20220916175337733.png)]

    2、映射

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jdnnFJWA-1663430283631)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20220916180631719.png)]

    3、排序

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E5D0YoY8-1663430283632)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20220916191336872.png)]

    4.2.3 Stream的终止操作

    1、匹配与查找

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmfpEpal-1663430283632)(C:\Users\86139\AppData在这里插入图片描述

    在这里插入图片描述

    2、归约

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PU1lykWe-1663430283634)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20220916223354197.png)]

    3、收集

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e2XoPw2o-1663430283634)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20220916230526803.png)]

    第5章 Optional类

    5.1 Optional引入

    • 到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,GOogle公司著名的Guava项目引入了Optional类,Guava通过使用检查控制的方式来防止代码被污染,它鼓励程序员写更干净的代码,受到Google的Guava的启发,Optional类已经成为Java8库类的一部分。
    • Optional 类(Java.util.Optional)是一个容器类,它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。
    • Optional类的javadoc描述如下:这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

    5.2 Optional类的方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9L8YXwXY-1663430283635)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20220916233312519.png)]

    本文章出自尚硅谷-宋红康的Java8新特性教程

    对宋老师的授课内容做的笔记。

  • 相关阅读:
    BEVFusion简介、环境配置与安装以及遇到的各种报错处理
    计算机网络原理 谢希仁(第8版)第四章习题答案
    论文解读|清华&Meta提出HorNet,用递归门控卷积进行高阶空间相互作用
    轻如鸿毛又重如泰山的电商运营,怎么干?
    Java Set类简介说明
    【算法】栈和队列常见算法
    Java数据结构之堆(Heap)
    删除word文档中的空白页
    Python自动化系统7
    java八股文面试[数据库]——MySQL中事务的特性
  • 原文地址:https://blog.csdn.net/weixin_48544279/article/details/126912707