为什么Stream操作与收集器重复? [英] Why Stream operations is duplicated with Collectors?
问题描述
请允许我提出一些投诉,也许这很有意思,但我想描述一下:为什么会提出这个问题?。
我已回答的问题与其他问题不同这里,这里和这里昨晚。
Please allow me to make some complaints, maybe it is boringly but I want to describe:"Why did this question will be raised?". I have answered questions is different from others here, here and here last night.
在我深入了解之后,我发现 Stream 和收集器违反了不要重复自己原则,例如: Stream#map & ; 收集器#mapping , Stream#filter & 收集器#过滤。
After I get dig into it, I found there are many duplicated logic between Stream and Collector that violates Don't repeat yourself principle, e.g: Stream#map & Collectors#mapping, Stream#filter & Collectors#filtering in jdk-9 and .etc.
但似乎合理,因为流遵守告诉,不要问原则/ 得墨忒耳定律和收集者遵守合成而非继承原则。
But it seems to reasonable since Stream abide by Tell, Don't ask principle/Law of Demeter and Collector abide by Composition over Inheritance principle.
I can only think of a few reasons why Stream operations is duplicated with Collectors as below:
We don't care of how the Stream is created in a big context. in this case Stream operation is more effectively and faster than Collector since it can mapping a Stream to another Stream simply, for example:
consuming(stream.map(...));
consuming(stream.collect(mapping(...,toList())).stream());
void consuming(Stream<?> stream){...}
Collector is more powerful that can composes Collectors together to collecting elements in a stream, However, Stream only providing some useful/highly used operations. for example:
stream.collect(groupingBy(
..., mapping(
..., collectingAndThen(reducing(...), ...)
)
));
Stream operations is more expressiveness than Collector when doing some simpler working, but they are more slower than Collectors since it will creates a new stream for each operation and Stream is more heavier and abstract than Collector. for example:
stream.map(...).collect(collector);
stream.collect(mapping(..., collector));
Collector can't applying short-circuiting terminal operation as Stream. for example:
stream.filter(...).findFirst();
是否有人可以提出其他不利条件/为什么Stream操作与收集器重复?我想重新理解它们。在此先感谢。
Does anyone can come up with other disadvantage/advantage why Stream operations is duplicated with Collectors here? I'd like to re-understand them. Thanks in advance.
推荐答案
链接一个专用的终端流操作可能会被那些用于链接方法调用的人更加表达,而不是组合收集器工厂调用的LISP样式。但它也允许流实现的优化执行策略,因为它知道实际操作而不是仅仅看到收集器
抽象。
Chaining a dedicated terminal stream operation might be considered more expressive by those being used to chained method calls rather than the "LISP style" of composed collector factory calls. But it also allows optimized execution strategies for the stream implementation, as it knows the actual operation instead of just seeing a Collector
abstraction.
另一方面,正如您自己命名的那样,可以组合 Collector
,允许在流操作所在的地方执行嵌入另一个收集器的这些操作不可能了。我想,这种镜像只在Java 8开发的后期才变得明显,这就是为什么有些操作缺少对应的原因,比如过滤
或 flatMapping
,它只存在于Java 9.因此,让两个不同的API做类似的事情,并不是在开发开始时做出的设计决定。
On the other hand, as you named it yourself, Collector
s can be composed, allowing to perform these operation embedded in another collector, at places where stream operations are not possible anymore. I suppose, this mirroring become apparent only at a late stage of the Java 8 development, which is the reason why some operations lacked their counterpart, like filtering
or flatMapping
, which will be there only in Java 9. So, having two different APIs doing similar things, was not a design decision made at the start of the development.
这篇关于为什么Stream操作与收集器重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!