JAVA研发狄仁杰 5万字:Stream和Lambda表达式最佳实践2( 六 )


spliterator){intcurrent=0;while(spliterator.tryAdvance(a->a.setName("testname".concat("-addnewname")))){current++;}returnThread.currentThread().getName()+":"+current;}复制代码
最后 , 写一下测试方法:@TestpublicvoiduseTrySplit(){Spliterator
split1=SpliteratorUsage.generateElements().spliterator();Spliterator
split2=split1.trySplit();log.info("beforetryAdvance:{}",split1.estimateSize());log.info("Characteristics{}",split1.characteristics());log.info(call(split1));log.info(call(split2));log.info("aftertryAdvance{}",split1.estimateSize());}复制代码
运行的结果如下:23:10:08.852[main]INFOcom.flydean.SpliteratorUsage-beforetryAdvance:50023:10:08.857[main]INFOcom.flydean.SpliteratorUsage-Characteristics1646423:10:08.858[main]INFOcom.flydean.SpliteratorUsage-main:50023:10:08.858[main]INFOcom.flydean.SpliteratorUsage-main:50023:10:08.858[main]INFOcom.flydean.SpliteratorUsage-aftertryAdvance0复制代码
List总共有1000条数据 , 调用一次trySplit之后 , 将List分成了两部分 , 每部分500条数据 。
注意 , 在tryAdvance调用之后 , estimateSize变为0 , 表示所有的元素都已经被处理完毕 。
再看一下这个Characteristics=16464 , 转换为16进制:Ox4050=ORDEREDorSIZEDorSUBSIZED这三个的或运算 。
这也是ArrayList的基本特征 。 13.breakstream的foreach
我们通常需要在javastream中遍历处理里面的数据 , 其中foreach是最最常用的方法 。
但是有时候我们并不想处理完所有的数据 , 或者有时候Stream可能非常的长 , 或者根本就是无限的 。
一种方法是先filter出我们需要处理的数据 , 然后再foreach遍历 。
那么我们如何直接break这个stream呢?今天本文重点讲解一下这个问题 。 13.1使用Spliterator
上篇文章我们在讲Spliterator的时候提到了 , 在tryAdvance方法中 , 如果返回false , 则Spliterator将会停止处理后续的元素 。
通过这个思路 , 我们可以创建自定义Spliterator 。
假如我们有这样一个stream:Stream
ints=Stream.of(1,2,3,4,5,6,7,8,9,10);复制代码
我们想定义一个操作 , 当x>5的时候就停止 。
我们定义一个通用的Spliterator:publicclassCustomSpliteratorextendsSpliterators.AbstractSpliterator{privateSpliteratorsplitr;privatePredicatepredicate;privatevolatilebooleanisMatched=true;publicCustomSpliterator(Spliteratorsplitr,Predicatepredicate){super(splitr.estimateSize(),0);this.splitr=splitr;this.predicate=predicate;}@OverridepublicsynchronizedbooleantryAdvance(Consumer
consumer){booleanhadNext=splitr.tryAdvance(elem->{if(predicate.test(elem)&&isMatched){consumer.accept(elem);}else{isMatched=false;}});returnhadNext&&isMatched;}}复制代码
在上面的类中 , predicate是我们将要传入的判断条件 , 我们重写了tryAdvance , 通过将predicate.test(elem)加入判断条件 , 从而当条件不满足的时候返回false.
看下怎么使用:@Slf4jpublicclassCustomSpliteratorUsage{publicstaticStreamtakeWhile(Streamstream,Predicatepredicate){CustomSpliterator
(stream.spliterator(),predicate);returnStreamSupport.stream(customSpliterator,false);}publicstaticvoidmain(String[]args){Stream
ints=Stream.of(1,2,3,4,5,6,7,8,9,10);List
result=takeWhile(ints,x->x<5).collect(Collectors.toList());log.info(result.toString());}}复制代码


推荐阅读