在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可以实现一直从流中丢弃元素,直到条件不成立,后续元素不再丢弃。