Java Stream Reduce的理解

1,118 阅读3分钟

Stream的reduce方法,翻译过来是聚合或者是汇聚成一个的意思,由于Stream本身就代表着一堆数据,那stream.reduce()方法顾名思义就是把一堆数据聚合成一个数据

理解了reduce方法的意思,再来看看这个方法挂靠的对象是stream,是一个流,了解一下流的工作方式: 流底层核心其实是Spliterator接口的一个实现,而这个Spliterator接口其实本身就是Fork/Join并行框架的一个实现,所以归根结底要明白流的工作方式,就要明白一下Fork/Join框架的基本思想,即:以递归的方式将可以并行的任务拆分成更小的子任务,然后将每个子任务的结果合并起来生成整体的最后结果,画了个草图如下

image.png

理解了方法本身的意思以及流的工作方式,再结合到一起理解一下stream.reduce()方法,即用Fork/Join的方式把一堆数据聚合成一个数据,因此可以画出reduce方法的运行草图

image.png

结合草图,要实现stream.reduce()方法,必须要告诉JDK

你有什么需求数据要汇聚?(Stream已经提供了数据源,对应上面草图的A元素) 最后要汇聚成怎样的一个数据类型(对应reduce方法的参数一,对应上面草图的B元素) 如何将需求数据处理或转化成一个汇聚数据(对应reduce方法的参数二,对应上面草图的汇聚方式1) 如何将多个汇聚数据进行合并(对应reduce方法的参数三,对应上面草图的汇聚方式2) 再结合你给的map方法,其实是要把I类数据的流,最后转化为一个O类数据的List,因此按照上面的步骤可以进行对照

你有什么需求数据要汇聚?(I类数据流) 最后要汇聚成怎样的一个数据类型(一个集合,new ArrayList()) 如何将需求数据处理或转化成一个汇聚数据(根据mapper把I转化为O,再用List.add方法) 如何将多个汇聚数据进行合并(两个集合合并,用List.addAll()) 最后补充一点,若是你的参数真是Stream stream和Function<I, O> mapper,建议不要用reduce方法,这么写可能会更好一点

public static <I, O> List<O> map(Stream<I> stream, Function<I, O> mapper) {
        return stream.map(mapper).collect(Collectors.toList());
    }

BinaryOperator是供多线程使用的,如果不在Stream中声明使用多线程,就不会使用子任务,自然也不会调用到该方法。另外多线程下使用BinaryOperator的时候是需要考虑线程安全的问题。 另外自问自答下为什么需要BinaryOperator 因为这个重载的方法和其他两个不相同,允许改变返回值,所以返回值并不一定是Collection的子类;因此必须显示的声明如何拼接两个子任务产生的结果。

摘自segmentfault