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


实际上 , 我们并不需要显示的assign一个predicate , 只要是满足predicate接口的lambda表达式都可以看做是一个predicate 。 同样可以调用and , or和negate操作:List
stringList4=Stream.of("a","ab","aac","ad").filter(((Predicate
)a->a.startsWith("a")).and(a->a.length()>1)).collect(Collectors.toList());log.info("{}",stringList4);复制代码14.5Predicate的集合操作
如果我们有一个Predicate集合 , 我们可以使用reduce方法来对其进行合并运算:@TestpublicvoidcombiningPredicateCollection(){List>allPredicates=newArrayList
a.startsWith("a"));allPredicates.add(a->a.length()>1);List
stringList=Stream.of("a","ab","aac","ad").filter(allPredicates.stream().reduce(x->true,Predicate::and)).collect(Collectors.toList());log.info("{}",stringList);}复制代码
上面的例子中 , 我们调用reduce方法 , 对集合中的Predicate进行了and操作 。 15.中构建无限的stream
在java中 , 我们可以将特定的集合转换成为stream , 那么在有些情况下 , 比如测试环境中 , 我们需要构造一定数量元素的stream , 需要怎么处理呢?
这里我们可以构建一个无限的stream , 然后调用limit方法来限定返回的数目 。 15.1基本使用
先看一个使用Stream.iterate来创建无限Stream的例子:@TestpublicvoidinfiniteStream(){Stream
infiniteStream=Stream.iterate(0,i->i+1);List
collect=infiniteStream.limit(10).collect(Collectors.toList());log.info("{}",collect);}复制代码
上面的例子中 , 我们通过调用Stream.iterate方法 , 创建了一个0 , 1 , 2 , 3 , 4....的无限stream 。
然后调用limit(10)来获取其中的前10个 。 最后调用collect方法将其转换成为一个集合 。
看下输出结果:INFOcom.flydean.InfiniteStreamUsage-[0,1,2,3,4,5,6,7,8,9]复制代码15.2自定义类型
如果我们想输出自定义类型的集合 , 该怎么处理呢?
首先 , 我们定义一个自定义类型:@Data@AllArgsConstructorpublicclassIntegerWrapper{privateIntegerinteger;}复制代码
然后利用Stream.generate的生成器来创建这个自定义类型:publicstaticIntegerWrappergenerateCustType(){returnnewIntegerWrapper(newRandom().nextInt(100));}@TestpublicvoidinfiniteCustType(){Supplier
randomCustTypeSupplier=InfiniteStreamUsage::generateCustType;Stream
infiniteStreamOfCustType=Stream.generate(randomCustTypeSupplier);List
collect=infiniteStreamOfCustType.skip(10).limit(10).collect(Collectors.toList());log.info("{}",collect);}复制代码
看下输出结果:INFOcom.flydean.InfiniteStreamUsage-[IntegerWrapper(integer=46),IntegerWrapper(integer=42),IntegerWrapper(integer=67),IntegerWrapper(integer=11),IntegerWrapper(integer=14),IntegerWrapper(integer=80),IntegerWrapper(integer=15),IntegerWrapper(integer=19),IntegerWrapper(integer=72),IntegerWrapper(integer=41)]复制代码16.自定义parallelStream的threadpool
之前我们讲到parallelStream的底层使用到了ForkJoinPool来提交任务的 , 默认情况下ForkJoinPool为每一个处理器创建一个线程 , parallelStream如果没有特别指明的情况下 , 都会使用这个共享线程池来提交任务 。
那么在特定的情况下 , 我们想使用自定义的ForkJoinPool该怎么处理呢?16.1通常操作
假如我们想做一个从1到1000的加法 , 我们可以用并行stream这样做:List
integerList=IntStream.range(1,1000).boxed().collect(Collectors.toList());ForkJoinPoolcustomThreadPool=newForkJoinPool(4);Integertotal=integerList.parallelStream().reduce(0,Integer::sum);log.info("{}",total);复制代码