函数式编程思想:对方法中的数据进行了什么操作
优点:代码简介、便于理解、易于并发编程
JDK8中的语法糖,可以对某些匿名内部类的写法进行简化
使用条件:匿名内部类是一个接口,并且接口只有一个抽象方法
核心原则:可推导可省略
基本格式
(参数列表)->{代码}
案例一
//未使用lambda
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("第一个线程启动了");
}
}).start();
//使用lambda
new Thread(()->
{
System.out.println("第二个线程启动了");
}).start();
}
案例二
选中接口类,alt+enter,可进行匿名内部类与lambda表达式的转换
//自定义方法,方法参数为抽象接口,且只有一个接口方法
public static int calculateNum(IntBinaryOperator operator)
{
int a=10;
int b=20;
return operator.applyAsInt(a,b);
}
//未进行lambda表达式
int i = calculateNum(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left + right;
}
});
System.out.println(i);
//lambda表达式
int i = calculateNum((int left, int right) -> {
return left + right;
});
System.out.println(i);
案例三
public class Main {
public static void main(String[] args) {
foreachArr((int abc)->
{
System.out.println(abc);
});
}
public static void foreachArr(IntConsumer intConsumer)
{
int[] arr={1,2,3,4,5,6,7,8,9,10};
for (int i:arr) {
intConsumer.accept(i);
}
}
}
终结:使用lambda表达式的时候,需要关注的是抽象类中的抽象方法参数与方法体
Lambda表达式省略机制:
1.参数类型可省略
2.方法体只有一句代码时大括号return和唯一一句代码的分号可省略
3.方法只有一个参数时,小括号可以省略
可以将数组或集合进行链状流式的操作不同于io流
//去重distinct()
//过滤filter()
//foreach遍历
List<Author> authors = test();
authors.stream().distinct().
filter(new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getAge() > 18;
}
})
.forEach(new Consumer<Author>() {
@Override
public void accept(Author author) {
System.out.println(author.getName());
}
});
//lambda表达式
List<Author> authors = test();
authors.stream().distinct().
filter(author -> author.getAge() > 18)
.forEach(author -> System.out.println(author.getName()));
}
stream的常见操作
一.创建流
1.单列集合:集合对象.stream()
2.数组:Arrays.stream(数组)或者使用Stream.of
3.双列集合:转换成单列集合后在创建
二.中间操作
1.filter,过滤
2.map,可以把流中的元素进行计算或转换
3.distinct,除去重复项
4.sorted,排序
如果使用的是空参的sorted方法,需要流中的元素实现了Comparable
4.limit,设置流的最大长度,超出的部分抛弃
例如:取排行榜的前三名
5.skip,跳过流中的n个元素,返回剩下的元素
6.flatMap
三.终结操作
1.foreach,对流中的元素进行遍历
2.count,统计数量
3.max&min,获取最值
4.collect,把流转换成集合
set集合
list集合
map集合,key值需要去重
5.查找与匹配,用来判断是否有符合匹配条件的元素,结果boolean
anyMatch,任何符合条件的
allMatch,都符合条件
noneMatch,没有符合条件的
findAny,获取流中的任意一个元素
//由于是随机取数,使用findAny方法返回值可能为空,
使用findAny进行匹配,如果有值则输出,没有值则无操作
findFirst,查找第一个元素
6.reduce归并
将stream流中的数据进行归并,即遍历处理流中的数据
案例一
案例二
Stream流的注意事项
1.没有终结操作,不会执行语句
2.流是一次性的,一旦进行终结操作,这个流就不能再用了
3.正常情况下,在流中处理数据不会影响原数据
parallel()
将串行流改为并行流,多个线程一同处理数据,提高工作效率,减少耗时
概述:只有一个抽象方法的接口
如果想要自定义函数式接口,需要在接口类上方添加@FunctionalInterface注解
检验和避免出现空指针异常
1.Optional对象的创建Optional.ofNullable()
2.安全消费值,即不报空指针错误
ifPresent()
orElseGet()
orElseThrow
3.数据过滤
filter
4.判断
5.数据转换
map
作用:使用lambda表达式的时候,对表达式进行简化
使用条件:方法体中只有一个方法的调用,包含构造方法,我们可以对代码进行进一步简化
格式=类名或对象名::方法名,可以使用alt+enter进行快捷简化