函数式编程Stream流(通俗易懂!!!)
目录
1.Lambda表达式
1.1 基本用法
1.2 省略规则
2.Stream流
2.1 常规操作
2.1.1 创建流
2.1.2 中间操作
filter
map
distinct
sorted
limit
编辑skip
flatMap
2.1.3 终结操作
foreach
count
max&min
collect
anyMatch
allMatch
noneMatch
编辑
findAny
findFirst
reduce归并
编辑2.2注意事项
3.Optional
3.1 概述
3.2 使用
3.2.1 创建对象
3.2.2 安全消费值
3.2.3 获取值
编辑 3.2.4 过滤
编辑3.2.5 判断
编辑3.2.6 数据转换
4.函数式接口
4.1 概述
4.2 常见函数式接口
4.3 常见的默认方法
编辑5.方法引用
5.1.1 引用类的静态方法
5.1.2 引用对象的实例方法
6.高级用法
基本数据类型优化
编辑并行流
重点:只关注传入的参数列表和方法体(数据+操作)
1.Lambda表达式
本质是匿名内部类的优化,先写匿名内部类
1.1 基本用法
public class lambdaTest {
public static void main(String[] args) {
// int i = calculateNum((int left, int right) -> {
// return left + right;
// });
// System.out.println(i);
//
// printNum((int value) -> {
// return value % 2 ==0;
// });
//
// Integer i1 = typeConver((String s)->{
// return Integer.valueOf(s);
// });
// System.out.println(i1);
foreachArr((int value) -> {
System.out.println(value);
});
}
public static void foreachArr(IntConsumer consumer){
int [] arr = {1,2,3,4,5,6,7,8,9,10};
for (int i : arr) {
consumer.accept(i);
}
}
public static <R> R typeConver(Function<String,R> function){
String str = "1235";
R result = function.apply(str);
return result;
}
public static void printNum(IntPredicate predicate){
int [] arr = {1,2,3,4,5,6,7,8,9,10};
for (int i : arr) {
if(predicate.test(i)){
System.out.println(i);
}
}
}
public static int calculateNum(IntBinaryOperator operator){
int a = 10;
int b = 20;
return operator.applyAsInt(a,b);
}
}
1.2 省略规则
- 参数类型可以省略
- 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
- 方法只有一个参数时小括号可以省略
- 以上规则都记不住也可以省略不记‘
2.Stream流
List<Object> array = new ArrayList<>();
array.stream() //把集合转换成流
.distinct() //去重
.filter(author -> author.getAge() < 18) //过滤年龄小于18的作者
.forEach(author -> System.out.println(author.getName())); //打印作者姓名
2.1 常规操作
2.1.1 创建流
2.1.2 中间操作
filter
- 可以对流中的元素进行条件过滤
map
- 可以把对流中的元素进行计算或转换
distinct
-
可以去除流中的重复元素
sorted
- 可以对流中的元素进行排序
limit
- 可以设置流的最大长度,超出的部分将被抛弃
skip
- 跳过流中的前n个元素,返回剩下的元素
flatMap
- map只能把一个对象转换另一个对象作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素
2.1.3 终结操作
foreach
count
- 可以用来获取当前流中元素的个数
max&min
- 可以用来获取流中的最大&最小值
collect
- 把当前流转成一个集合
anyMatch
- 可以用来判断是否有任意符合匹配条件的元素,结果为boolean类型
allMatch
- 可以用来判断是否都符合匹配条件
noneMatch
findAny
- 查找任意元素
findFirst
reduce归并
- 对流中的数据按照你指定的计算方式计算出一个结果(缩减操作)
- reduce的作用是把stream的元素给组合起来,我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和在初始化值的基础上进行计算,计算结果再和后面的元素计算
2.2注意事项
- 惰性求值(如果没有终结操作,)
- 流是一次性的(一旦一个流对象经过一个终结操作后,这个不能再被使用)
- 不会影响原数据
3.Optional
3.1 概述
我们在编写代码的时候出现最多的就是空指针异常。所以在很多情况下我们需要做各种非空的判断。
3.2 使用
3.2.1 创建对象
Optional就好像是包装类,可以把我们的具体数据封装Optional对象内部。然后我们去使用Optional中封装好的方法操作封装进去的数据就可以避免空指针异常。
3.2.2 安全消费值
3.2.3 获取值
不推荐使用
3.2.4 过滤
3.2.5 判断
3.2.6 数据转换
4.函数式接口
4.1 概述
只有一个抽象方法的接口我们称之为函数式接口
JDK的函数式接口都加上了@Functionallnterface注解进行标识。
4.2 常见函数式接口
- Consumer消费接口
- Function计算转换接口
- Predicate判断接口
- Supplier生产型接口
4.3 常见的默认方法
- and
- or
- negate
5.方法引用
推荐用法:快捷键
我们在使用lambda时,如果方法体只有一个方法的调用的话(包括构造方法)。可以使用方法引用
类名或者对象名:方法名
5.1 语法详解
5.1.1 引用类的静态方法
格式:类名::方法名