例如这个练习题,使用reduce和lambda表达式来实现map。
不明白的是reduce第三个参数的意义,感觉多此一举
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
public class MapUsingReduce {
public static <I, O> List<O> map(Stream<I> stream, Function<I, O> mapper) {
return stream.reduce(new ArrayList<O>(), (acc, x) -> {
// We are copying data from acc to new list instance. It is very inefficient,
// but contract of Stream.reduce method requires that accumulator function does
// not mutate its arguments.
// Stream.collect method could be used to implement more efficient mutable reduction,
// but this exercise asks to use reduce method.
List<O> newAcc = new ArrayList<>(acc);
newAcc.add(mapper.apply(x));
return newAcc;
}, (List<O> left, List<O> right) -> {
// We are copying left to new list to avoid mutating it.
List<O> newLeft = new ArrayList<>(left);
newLeft.addAll(right);
return newLeft;
});
}
}
下面是文档的说明,仍然不明白。。。
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions. This is equivalent to:
U result = identity; for (T element : this stream) result = accumulator.apply(result, element) return result;
but is not constrained to execute sequentially.
The identity value must be an identity for the combiner function. This means that for all u, combiner(identity, u) is equal to u. Additionally, the combiner function must be compatible with the accumulator function; for all u and t, the following must hold:
combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
望指教,谢谢!
我觉得可以这样理解
首先理解方法本身的意思:
Stream
的reduce
方法,翻译过来是聚合或者是汇聚成一个的意思,由于Stream
本身就代表着一堆数据,那stream.reduce()
方法顾名思义就是把一堆数据聚合成一个数据理解了
reduce
方法的意思,再来看看这个方法挂靠的对象是stream
,是一个流,了解一下流的工作方式:流底层核心其实是
Spliterator
接口的一个实现,而这个Spliterator
接口其实本身就是Fork/Join并行框架的一个实现,所以归根结底要明白流的工作方式,就要明白一下Fork/Join框架的基本思想,即:以递归的方式将可以并行的任务拆分成更小的子任务,然后将每个子任务的结果合并起来生成整体的最后结果,画了个草图如下理解了方法本身的意思以及流的工作方式,再结合到一起理解一下
stream.reduce()
方法,即用Fork/Join的方式把一堆数据聚合成一个数据,因此可以画出reduce
方法的运行草图结合草图,要实现
stream.reduce()
方法,必须要告诉JDK
Stream
已经提供了数据源,对应上面草图的A
元素)reduce
方法的参数一,对应上面草图的B
元素)reduce
方法的参数二,对应上面草图的汇聚方式1)reduce
方法的参数三,对应上面草图的汇聚方式2)再结合你给的
map
方法,其实是要把I
类数据的流,最后转化为一个O
类数据的List
,因此按照上面的步骤可以进行对照I
类数据流)new ArrayList()
)I
转化为O
,再用List.add
方法)List.addAll()
)最后补充一点,若是你的参数真是
Stream<I> stream
和Function<I, O> mapper
,建议不要用reduce
方法,这么写可能会更好一点