reduce和collect都是一种聚合操作。
本篇文章就是reduce和collect聚合函数自定义静态方法实现
reduce实现filter
private static <T> List<T> reduceFilter(List<T> list, Predicate<T> p){
List<T> ret = new ArrayList<>();
return list.stream().reduce(ret,(acc,cur) -> {
if (p.test(cur)){
acc.add(cur);
}
return acc;
},(list1,list2) ->{
return list1;
});
}
collect实现filter
private static <T> List<T> colFilter(List<T> list,Predicate<T> predicate){
return list.stream().collect(ArrayList::new,(acc,cur) ->{
if (predicate.test(cur)){
acc.add(cur);
}
},
(list1,list2) ->{
list1.addAll(list2);
});
}
reduce实现map映射
private static <T,R> List<R> reduceMap(List<T> list, Function<T,R> function){
List<R> ret = new ArrayList<>();
return list.stream().reduce(ret, (acc, curr)->{
R newValue = function.apply(curr);
acc.add(newValue);
return acc;
},
(list1,list2) -> {return list1;} );
}
collect实现map映射
private static <T,R> List<R> colMap(List<T> list ,Function<T,R> function){
return list.stream().collect(ArrayList<R>::new,
(acc,cur)->{
acc.add(function.apply(cur));
},(x,y) ->{
x.addAll(y);
} );
}
collect实现group分组
private static <T,R> List<R> colMap(List<T> list ,Function<T,R> function){
return list.stream().collect(ArrayList<R>::new,
(acc,cur)->{
acc.add(function.apply(cur));
},(x,y) ->{
x.addAll(y);
} );
}
总而言之,reduce和collect都是用来做一些聚合操作,现在来看看有啥区别
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
identity:初始值
accumulator:函数用于累计
combiner:汇总所有线程得到的结果
identity:主要作用用于定义返回值类型以及初始值类型
BiFunction<U, ? super T, U> accumulator
accumulator接收U,T类型,最终返回U类型返回值
(acc,cur) -> {
if (p.test(cur)){
acc.add(cur);
}
return acc;
}
这段主要就是accumulator函数
acc:起始值+函数中操作之后的值
cur:元素当前值
return acc主要是为了将acc聚合操作之后,重新赋值给下一轮的acc
accumulator函数聚合示意图:
Demo
List<Integer> list = new ArrayList<>();
list.add(11);
list.add(22);
list.add(33);
list.add(44);
list.add(55);
int a =0;
Integer total = list.stream().reduce(a,(acc,cur) ->{
System.out.println("起始值"+a);
System.out.println("acc"+acc);
System.out.println("cur"+cur);
return acc+cur;
});
System.out.println("total"+total);
由此可以看出,reduce聚合操作时不会影响数据改变,最终只是将聚合操作完的数据返回
collect:
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
supplier: 初始值(容器container)
accumulator:聚合函数主要用于做聚合操作
combiner:将多个线程的容器结合到一起最后做finish操作
collect聚合示意图:
List<Integer> list = new ArrayList<>();
list.add(11);
list.add(22);
list.add(33);
list.add(44);
list.add(55);
List<Integer> total = list.stream().collect(ArrayList::new, (acc,cur) -> {
System.out.println("acc"+acc);
System.out.println("cur"+cur);
acc.add(cur);
},(list1, list2) -> {
list1.addAll(list2);
});
System.out.println("total"+total);
}
由以上代码可以看出,reduce是将聚合之后的acc作为下一次的参数再聚合,然而collect中accumulator聚合函数<Biconsumer>是将acc直接添加到目标supplier构造出数据中