ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java流式编程(十七)dropWhile

2021-07-31 22:00:34  阅读:223  来源: 互联网

标签:predicate java 流式 take opWrapSink dropWhile public Op


目录


前言

在jdk9中,Stream中提供了dropWhile的功能。


一、示例

	@Test
    public void testDropWhile(){
        List<Integer> list = List.of(1, 2, 3, 4, 5, 4, 3, 2, 1);
        Stream<Integer> dropWhile = list.stream().dropWhile(i -> i < 4);
        dropWhile.forEach(System.out::println);
    }

结果

4
5
4
3
2
1

可以看出,开始时小于4的数被drop掉了,后续的数不在drop。

二、原理

在Stream接口的实现类ReferencePipeline中,定义的dropWhile( )方法的实现

 @Override
    public final Stream<P_OUT> dropWhile(Predicate<? super P_OUT> predicate) {
        return WhileOps.makeDropWhileRef(this, predicate);
    }

进入WhileOps的makeDropWhileRef( )方法,构造了一个有状态的内部类Op,重写了opWrapSink( )

static <T> Stream<T> makeDropWhileRef(AbstractPipeline<?, T, ?> upstream,
                                          Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
		//内部类Op继承StatefulOp
        class Op extends ReferencePipeline.StatefulOp<T, T> implements DropWhileOp<T> {
            public Op(AbstractPipeline<?, T, ?> upstream, StreamShape inputShape, int opFlags) {
                super(upstream, inputShape, opFlags);
            }
			......
            @Override
            //重写opWrapSink()
            Sink<T> opWrapSink(int flags, Sink<T> sink) {
                return opWrapSink(sink, false);
            }

            public DropWhileSink<T> opWrapSink(Sink<T> sink, boolean retainAndCountDroppedElements) {
            	//方法内部类OpSink
                class OpSink extends Sink.ChainedReference<T, T> implements DropWhileSink<T> {
                    long dropCount;
                    boolean take;

                    OpSink() {
                        super(sink);
                    }

                    @Override
                    //流中元素处理的方法
                    public void accept(T t) {
                    	//取数据的条件
                        boolean takeElement = take || (take = !predicate.test(t));

                        // If ordered and element is dropped increment index
                        // for possible future truncation
                        if (retainAndCountDroppedElements && !takeElement)
                        	//不符合取数据的条件,丢弃数量增加1
                            dropCount++;

                        // If ordered need to process element, otherwise
                        // skip if element is dropped
                        if (retainAndCountDroppedElements || takeElement)
                        	//符合取数据的条件,执行下行流操作
                            downstream.accept(t);
                    }

                    @Override
                    public long getDropCount() {
                        return dropCount;
                    }
                }
                //返回方法内部类OpSink
                return new OpSink();
            }
        }
        //最外层方法返回Op
        return new Op(upstream, StreamShape.REFERENCE, DROP_FLAGS);
    }

预言型接口predicate是传入的i -> i < 4,

通过accept方法,可以看出取数据的条件时takeElement 为true的时候,

boolean takeElement = take || (take = !predicate.test(t));

符合条件时,predicate.test(t)预言通过,丢弃该元素,take为false;

不符合条件时,predicate.test(t)预言不通过,元素不丢弃,take变为true;

当take变为true后,后续元素不再丢弃,全部进行处理。

总结

dropWhile可以实现一直从流中丢弃元素,直到条件不成立,后续元素不再丢弃。

标签:predicate,java,流式,take,opWrapSink,dropWhile,public,Op
来源: https://blog.csdn.net/RenshenLi/article/details/119281671

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有