Java8新特性

JDK8新特新

第一章 java8的优势

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

第2章 lambda表达式

2.1 简介

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

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

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();
}

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;
    }
}

其他函数式接口

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

第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);
    }


}

第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新特性教程

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁小樽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值