目录
JDK8新特新
第一章 java8的优势
- 速度更快
- 代码更少(增加了新语法lambda式)
- 强大的StreamAPI
- 便于并行
- 最大化减少空指针异常Optional
- Nashorn引擎,允许在JVM上运行JS应用
第2章 lambda表达式
2.1 简介
Lambda 表达式:在java8语言引入的一种心得语法元素和操作符,这个操作符为 “->” ,该操作符被统称为Lambda操作符或者箭头操作符。它将Lambda分为两个部分:
* -> :lambda操作符,也称箭头操作符 * -> 左边是 lambda形参列表 (接口中抽象方法的形参列表) * -> 右边是 lambda体 (重写的抽象方法的方法体)
2.2 使用语法
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、筛选与切片
2、映射
3、排序
4.2.3 Stream的终止操作
1、匹配与查找
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmfpEpal-1663430283632)(C:\Users\86139\AppData
2、归约
3、收集
第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类的方法
本文章出自尚硅谷-宋红康的Java8新特性教程
对宋老师的授课内容做的笔记。