一、lambda表达式
1.函数式接口
有且仅有一个抽象方法的接口
@FunctionalInterface定义一个函数式接口
语法糖
语法糖是指使用更加方便,但是原理不变的代码语法
2.语法格式
(o1,o2) -> Integer.compare(o1,o2);
->是Lambda操作符或箭头操作符
->左边是Lambda形参列表(其实就是接口中的抽象方法的形参列表)
->右边是lambda体(Lambda 表达式要执行的功能/重写的接口的方法
3.简化lambda表达式
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
4.变量作用域
访问局部变量要注意如下 3 点:
可以直接在 Lambda 表达式中访问外层的局部变量;
在 Lambda 表达式当中被引用的变量的值不可以被更改;(本质上因为lambda用的是内部类)
在 Lambda 表达式当中不允许声明一个与局部变量同名的参数(包括参数的名称也不能一样)
5.四大内置核心函数式接口
内置接口:Cousumer<T>、Supplier<T>、Function<T R>、Predicate<T>
Cousumer<T>
Supplier<T>
Function<T R>
Predicate<T>
6.方法引用
双冒号:: 为引用运算符,而它所在的表达式被称为方法引用, 如果Lambda要表达的函数方案已经存在于某个方法的实现中,那么则可以通过双冒号来引用该方法作为Lambda的替代者
(1.)构造方法引用
格式:类名::new
要调用构造器的参数列表要与函数式接口中抽象方法的参数列表一致,可以是一个参数,也可以是多个参数
符合 (方法参数)-> new 对象(构造参数) 这样的类型,就可以使用 对象::new , 如果是有参的构造,参数由方法参数决定
(2.)静态方法引用
格式:类名::静态方法名
本质要求: 接口中的方法调用了另一个类的静态方法。要求两个方法的参数要一致
(3.)实例方法引用
格式:对象名::方法名
本质要求:接口的方法调用了对象的方法.要求两个方法的参数要一致</font>
(4.)对象方法引用
格式: 类名::方法名
条件:在抽象方法中,参数作为实例方法调用者,就可以简化
二、Stream流
1.流式思想
类似于生产流水线
2.概念
主要操作的对象是集合,可以执行非常复杂的查找、过滤和映射数据等操作
3.Stream创建
可以通过Collection系列集合提供的stream()或者paralleStream()来创建
通过Arrays中的静态方法stream()获取数组流
通过Stream中的静态方法of()
创建无限流 iterate(),generate()
Collection
通过Arrays中的静态方法stream()获取数组流
通过Stream中的静态方法of()
创建无限流 iterate(),generate()
装箱
4.Stream流的中间操作
Filter 从stream流中过滤某些元素
Limit 截断流,使其元素不超过指定数量
skip 跳过元素
distinct 筛选,去除重复元素
sort 流中的数据排序
map 映射
filter
limit
skip
distinct
sort
Map
5.Stream流的终端操作
查找与匹配
allMatch 检查是否匹配所有元素
anyMatch 检查是否至少匹配一个元素
noneMatch 检查是否没有匹配所有元素
findFirst 返回第一个元素
findAny 返回当前流中的任意元素
count 返回流中元素的总个数
max 返回流中最大值
min 返回流中最小值
归约(reduce)
元素累加,一般用作加法计算
收集(collect)
就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合
返回list集合
返回set集合
返回Map集合
分组 groupingBy
6.Optional
是个容器:它可以保存类型T的值,或者仅仅保存null。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象
常用方法:
isPresent() 返回容器中是否有值,有值 true
optional.get() 从容器中获取值,如果没有值,会抛出异常
ifPresent(消费一个数据) 如果容器中有数据,我们该怎么处理这个数据
orElse(值) 是前两个方法的组合,如果容器中有数据,就返回容器中的数据,没有的话,使用括号中的值