问题描述
链接专用终端流操作可能会被那些用于链接方法调用的人表示,而不是组成收集器工厂调用的“
LISP风格”,更具表达性。但它也允许针对流实现的优化执行策略,因为它知道实际的操作,而不仅仅是看到Collector
抽象。
另一方面,正如您自己命名的那样,Collector
可以组成s,从而允许在不再可能进行流操作的位置执行嵌入到另一个收集器中的这些操作。我想,这种镜像仅在Java
8开发的后期才变得明显,这就是为什么某些操作缺少对应的操作(如filtering
or )的原因,而这些操作flatMapping
仅在Java
9中才存在。因此,让两个不同的API进行相似的操作,不是在开发之初就做出的设计决定。
解决方法
在深入研究之后,我发现Stream和Collector之间存在许多重复的逻辑,这些逻辑违反了不要重复自己的原则,例如:jdk-9和中的Stream#map&Collectors#mapping,Stream#filter&Collectors#filtering。等等
但自从溪流遵守告诉,不要问得墨meter耳的法则/
得墨Law律和集热器遵守继承构成原则看来,这是合理的。
我只能想到以下几个原因,为什么用Collector重复Stream操作:
consuming(stream.map(...));
consuming(stream.collect(mapping(...,toList())).stream());
void consuming(Stream<?> stream){...}
-
Collector更强大,可以将Collector组合在一起,以收集流中的元素,但是,Stream仅提供一些有用/经常使用的操作。例如:
stream.collect(groupingBy(
…,mapping(
…,collectingAndThen(reducing(…),…)
)
)); -
当执行一些更简单的工作时,Stream操作比Collector更具表达性,但它们比Collector慢得多,因为它将为每个操作创建一个新的Stream,并且Stream比Collector更加繁重和抽象。例如:
stream.map(...).collect(collector);
stream.collect(mapping(…,collector));
-
stream.filter(...).findFirst();
有谁能提出其他缺点/优势,为什么在此处使用收集器复制Stream操作?我想重新理解它们。提前致谢。