美文网首页
java-stream(二)

java-stream(二)

作者: go_2021 | 来源:发表于2022-01-07 22:55 被阅读0次
    源码是如何实现的

    我们随便其中一个方法,比如filter,然后在ReferencePipeline类中找到方法的实现:

    @Override
        public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
            Objects.requireNonNull(predicate);
            return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
                                         StreamOpFlag.NOT_SIZED) {
                @Override
                Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                    return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                        @Override
                        public void begin(long size) {
                            downstream.begin(-1);
                        }
    
                        @Override
                        public void accept(P_OUT u) {
                            if (predicate.test(u))
                                downstream.accept(u);
                        }
                    };
                }
            };
        }
    

    返回Stream这是链式操作的关键,大致分为2层StateLessOp可以看为一个ReferencePipeline,OpWrapSink可以理解为一个sink。
    ReferencePipeline有一些StreamOpFlag和StreamShape的属性,还有StatelessOp特性。
    sink理解为水槽,水槽里有我们要执行的操作,分为begin,accept,end方法,accept里放的就是我们实现的业务逻辑。
    继续一层层跟进我们到了AbstractPipiline的构造方法:


    这里把ReferencePipeline形成了一个双向链表:


    如何运行的

    在运行时打断点发现,关键代码在AbstractPipeline的copyInto方法。




    分析可得,假如我们的流是stream.limit(2).filter().map().count()
    中间操作的执行流程就是
    limit->begin()->filter->begin()->map->begin()
    for(list中的元素1,2,3){
    1limit->accept()->filter->accept()->map->accept()
    2limit->accept()->filter->accept()->map->accept()
    3limit->accept()没有通过}
    limit->end()->filter->end()->map->end()
    这就是操作组合后的执行过程也是实现流只需一次循环。

    如何判断短路操作的

    如图中的combinedFlags成员变量,会根据前后的OpFlags来判断是否是短路操作。



    又是上面的一张图,此时会走else逻辑:



    forEachWithCancel就是短路操作的关键。

    一些技巧

    • 强转类型
    arrayList.stream().map(x -> (JSONObject) x).filter(x -> {
               //本来就是JSONObject类型却不能在filter中强转获取,可以加一层强转map
            }).findAny().get();
    

    相关文章

      网友评论

          本文标题:java-stream(二)

          本文链接:https://www.haomeiwen.com/subject/xppqcrtx.html