响应式编程 Lambda、Funcation、Stream 要点总结
- 只包含一个非
default
方法的接口,就可以是函数式接口。函数式接口除了有且仅有一个必须的抽象方法之外,其他更多方法必须是 default 默认实现的方法。可以使用注解@FunctionalInterface
修饰在接口上来校验该接口是否可以是函数式接口。 - 一个接口中定义的方法,被实现的可能性越多,并且每种可能性实现的方法体代码越少,这种方法越适合被定义为函数式接口方法。例如Java内置的
BiFunction
,它定义了一个方法,方法接收2个参数,然后对这2个参数进行组合或者计算得出一个结果。 - 主要的几个函数式接口:消费者
Consumer
、提供者Supplier
、数据转换Function
、数据判断Predicate
。对应Bi
开头的就是入参多一些。 Lambda
表达式中,只有当方法签名(参数列表和返回类型)与函数式接口的方法签名完全匹配时,才能使用方法引用。Stream
流处理,由(创建流、中间处理操作、结果操作)三大环节组成,其中中间处理操作可以有N个,最后的终止操作只能有一个。例如创建流之后,可以有N个filter
、map
,但是结果操作max
、count
这种只能在最后且只能有一个。- 进入Stream类中查看所有方法的注释,只要注释标注
This is an intermediate operation.
的就是中间操作,标注This is a terminal operation.
的就是最后终止操作。 - 流处理默认使用当前线程单线程处理,可以通过
parallel()
方法设置为并行流进行并发执行。并发执行时候要特别注意尽量不要在流操作块内部使用代码块之外的共享变量。如果有使用,请注意线程并发安全问题,原则上流处理的代码块中尽量不处理代码块以外的共享变量。 - 流处理其中的每条数据的规则是:每条数据单独走完一个完整的流水线后,然后才进行下一个元素的完整流水线处理,直到处理完流中的所有数据。
- 一般常用
peek
方法用来调试使用,可以用它来输出每一步处理后的结果。 - 建议熟悉
reduce
方法的使用,很多场景下的数据收集和聚合会使用它。 - 建议了解
takeWhile
方法的使用,一般拿它和 filter 对比,filter
会遍历完所有数据,而takeWhile
一旦遇到第一个不满足条件的元素时就直接结束流,不会再继续遍历后面的元素。 - 建议熟悉
groupingBy
的使用,例如将一个对象集合按照对象中的指定字段进行分组的业务场景很常见,它返回一个Map<groupKey, List<T>>
结果。 - 流处理管道中的步骤,建议将缩小范围的操作尽可能靠前执行,例如
limit
、filter
。 - 所有
for
循环处理集合的场景,强烈建议改用Stream
方式处理。 - 流的整体代码执行,是
lazy
机制的,所有代码只有在执行终止类型这样的方法时才会执行。
(END)