为什么Stream操作与收集器重复? [英] Why Stream operations is duplicated with Collectors?

查看:124
本文介绍了为什么Stream操作与收集器重复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请允许我提出一些投诉,也许这很有意思,但我想描述一下:为什么会提出这个问题?
我已回答的问题与其他问题不同这里这里这里昨晚。

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:


  1. 我们不关心 Stream 是在大的上下文中创建的。在这种情况下, Stream 操作是比收藏家更有效,更快捷因为它可以映射 Stream 到另一个 Stream 例如:

  1. 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));
    


  • 收集器无法将短路终端操作应用为 Stream 。例如:

  • 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, Collectors 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆