Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

java - 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.

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. 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){...}
    
  2. 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(...), ...)
           )
    ));
    
  3. 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));
    
  4. Collector can't applying short-circuiting terminal operation as Stream. for example:

    stream.filter(...).findFirst();
    

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...