Java8 新特性之 Lambda 和 Stream
(一) Lambda
1. what?
Lambda是 java8 的一个新特性,可以大幅度减少代码量;
关注于"做什么",而不是"怎么做",可以通过匿名内部类理解;
虽然减少了代码量,但是可读性差;
2. why?
简单快速的满足一些要求,如获取并行流对象
3. how?
表达式: ( ) -> { }
左侧代表 Lambda 所需的所有参数,右边是 Lambda 要执行的功能(方法体)
注:
( ) 内参数只有1个时,可以去掉括号;
{ }内方法体只有1个时,可以去掉花括号
( )不需要写参数类型
右侧如果只有一个表达式返回值,return 可以省略
(1) 4个常用的函数式接口
所谓函数式接口,就是 该接口有且仅有1个抽象方法,通常会贴有标签@FunctionalInterface
重点区分:4个常用的函数式接口她们的特点和特征是什么
参数类型 | 返回类型 | 特点 | |
---|---|---|---|
Consumer 消费型接口 | T | void | 对类型T的对象进行操作 方法 : void accept(T t) |
Function 函数型接口 | T | R | 对类型T的对象进行操作 , 返回类型是R的对象 |
Supplier 供给型接口 | T | 返回类型为T的对象 方法 : T get( ) ; |
|
Predicate 断言型接口 | T | boolean | 判断对象T是否满足条件 , 返回boolean值 方法: boolean test ( T t ) ; |
(2) 方法引用的语法
类名::静态方法名
对象::实例方法名
类名::实例方法名
类名::new (构造器引用 )
类型[]::new (数组引用)
(二) Stream
1. what?
Stream是对数据进行操作的一个工具,封装了一些好用的方法
Stream流的特点:属于管道流,只能被使用一次。第一个Stream流调用完毕方法,数据就会流到下一个Stream上(可以看成是流水线操作),所以第一个Stream流不能再调用方法。
2. why?
传统集合操作数据流程复杂,Stream提供的API大大缩减了代码量
3. how?
- 创建一个Steam流对象
- 根据需求调用方法
- 若要输出,forEach( ),用了forEach( )就不能再进行链式操作了,Stream流已经关闭了。
(1) 创建Stream对象的5种方式
1> 调用 stream();//并发
调用 parallelStream();//并行
2> Arrays.stream(); // 可以传入一个数组
3> Stream.of(); // 可以传入任意类型
4> Stream.iterate(); //无限流 第一个参数可以指定开始的值,第二个参数填写规则
5> Stream.generate(new Supplier接口) //无限流 ,可用于产生随机数等
(2) 常用API
filter() (传入判断规则过滤筛选出)
distinct() 去重,不需要传入参数
limit() (无限流可以限制其输出多少个)
skip() (传入需要跳过的个数)
map() 对传入的集合进行操作,然后返回;操作前后元素数量相同
flatmap() 对传入的两个集合进行整合,返回一个新的Stream流
排序:
sort() 不传参自然排序,传参可自定义排序规则
匹配:
allMatch(); 全部元素都匹配条件,返回ture
anyMatch(); 任意一个元素匹配
noneMatch() 全部元素都不满足条件,返回true
findFirst() 返回第一个元素(Optional类型)
findAny() 返回任意一个元素,常用于并行流ParallelStream
统计:
count() 统计个数
max()
min()
汇总
reduce(第一个参数是x,第二个参数是x和y的操作,如x+y) , 返回一个值
collect(Collectors. )可以生成一个集合,如map set等等
分组分区
collect(Collectors.groupingBy(new 函数型接口)) 根据某个参数分组,可以分多个组
collect(Collectors.partitioningBy(new 断言型接口)) 根据某个条件分区,true区和false区