在 Stream 的处理过程中,我们有时会遇到写 if/else
的情况,而带有 if/else
的逻辑通常会有些长。在写 lambda 表达式时,我们又需要尽量写简洁的语句。那么,对于含有判断语句的情况,该怎么处理?
针对 if/else
通常有以下几种场景:
- if
- if else
- if else if else if else
- 嵌套 if/else
在 Stream 的处理过程中,我们有时会遇到写 if/else
的情况,而带有 if/else
的逻辑通常会有些长。在写 lambda 表达式时,我们又需要尽量写简洁的语句。那么,对于含有判断语句的情况,该怎么处理?
针对 if/else
通常有以下几种场景:
- if
- if else
- if else if else if else
- 嵌套 if/else
JDK 内置的收集器基础上已经可以满足我们的日常开发需求,但有时候我们也可能会遇到不满足的情况,这种情况下我们可以自定义收集器来完成我们的需求。
1 | public interface Collector<T, A, R> { |
可以看出,收集器内部有一个抽象接口需要我们来实现。
Stream 虽然已经提供了不少终止操作,但是可能在有些场景下还是无法满足你的使用要求。没关系,如果你发现你想要的终止操作功能接口 Stream 没有提供,不妨试试从 collect
方法查找一下,很大概率上你会有意外收获。
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);<R, A> R collect(Collector<? super T, A, R> collector);
collect
提供了两个方法,一个是三参数方法,单看参数的话,其实和 reduce
特别像。单参数的方法,需要传入一个收集器。其实点进收集器内部不难发现,Collector
内部定义了三参数方法需要的所有内容。二者的作用都是将流内元素按照一定的要求汇聚成一个最终结果。
1 | public interface Collector<T, A, R> { |
从 collect
方法的返回类型来看,collect
方法的主要作用是将流所有元素汇聚成一个值。从某种意义讲,其实也是 reduce
。
Stream 提供了 reduce
方法,顾名思义,是将流内的元素按照一定的规则汇聚成一个值。
在了解 reduce
之前,我们来先思考一个问题:我们需要哪些内容才能完成汇聚操作?
- 数据
- 汇聚结果类型
- 汇聚方案
而 Stream 本身就是数据源,所以我们只要专注思考我们想要什么类型的返回数据,以及怎么样把数据汇聚起来。
Optional<T> reduce(BinaryOperator<T> accumulator)
这个方法的入参 BinaryOperator
,是一个二元操作的函数式接口,也就是提供了数据汇聚的方案。reduce
的过程是分而治之的过程,这个过程不是一步完成的,是元素两两合并,结果再两两合并,直到有最终结果,返回类型为 Optional
。
其实这部分在 JavaDoc 里用代码解释的很明白,计算得到的初始值用的是取到的第一个元素。整体过程是把流所有的元素合并成一个值,合并的规则是在 accumulator.apply
里定义的。
在使用 Stream 的过程中,还是有不少场景需要将流内的元素转成数组。Stream 提供了两个方法给我们将之转为数组。
- toArray()
- toArray(IntFunction<A[]> generator)
我就问一句,我能先说第二个吗?