怎么break java8 stream的foreach
文章目錄
- 簡介
- 使用Spliterator
- 自定義forEach方法
- 總結
怎么break java8 stream的foreach
簡介
我們通常需要在java stream中遍歷處理里面的數據,其中foreach是最最常用的方法。
但是有時候我們并不想處理完所有的數據,或者有時候Stream可能非常的長,或者根本就是無限的。
一種方法是先filter出我們需要處理的數據,然后再foreach遍歷。
那么我們如何直接break這個stream呢?今天本文重點講解一下這個問題。
使用Spliterator
上篇文章我們在講Spliterator的時候提到了,在tryAdvance方法中,如果返回false,則Spliterator將會停止處理后續的元素。
通過這個思路,我們可以創建自定義Spliterator。
假如我們有這樣一個stream:
Stream<Integer> ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);我們想定義一個操作,當x > 5的時候就停止。
我們定義一個通用的Spliterator:
public class CustomSpliterator<T> extends Spliterators.AbstractSpliterator<T> {private Spliterator<T> splitr;private Predicate<T> predicate;private volatile boolean isMatched = true;public CustomSpliterator(Spliterator<T> splitr, Predicate<T> predicate) {super(splitr.estimateSize(), 0);this.splitr = splitr;this.predicate = predicate;}@Overridepublic synchronized boolean tryAdvance(Consumer<? super T> consumer) {boolean hadNext = splitr.tryAdvance(elem -> {if (predicate.test(elem) && isMatched) {consumer.accept(elem);} else {isMatched = false;}});return hadNext && isMatched;} }在上面的類中,predicate是我們將要傳入的判斷條件,我們重寫了tryAdvance,通過將predicate.test(elem)加入判斷條件,從而當條件不滿足的時候返回false.
看下怎么使用:
@Slf4j public class CustomSpliteratorUsage {public static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<T> predicate) {CustomSpliterator<T> customSpliterator = new CustomSpliterator<>(stream.spliterator(), predicate);return StreamSupport.stream(customSpliterator, false);}public static void main(String[] args) {Stream<Integer> ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> result =takeWhile(ints, x -> x < 5 ).collect(Collectors.toList());log.info(result.toString());} }我們定義了一個takeWhile方法,接收Stream和predicate條件。
只有當predicate條件滿足的時候才會繼續,我們看下輸出的結果:
[main] INFO com.flydean.CustomSpliteratorUsage - [1, 2, 3, 4]自定義forEach方法
除了使用Spliterator,我們還可以自定義forEach方法來使用自己的遍歷邏輯:
public class CustomForEach {public static class Breaker {private volatile boolean shouldBreak = false;public void stop() {shouldBreak = true;}boolean get() {return shouldBreak;}}public static <T> void forEach(Stream<T> stream, BiConsumer<T, Breaker> consumer) {Spliterator<T> spliterator = stream.spliterator();boolean hadNext = true;Breaker breaker = new Breaker();while (hadNext && !breaker.get()) {hadNext = spliterator.tryAdvance(elem -> {consumer.accept(elem, breaker);});}} }上面的例子中,我們在forEach中引入了一個外部變量,通過判斷這個外部變量來決定是否進入spliterator.tryAdvance方法。
看下怎么使用:
@Slf4j public class CustomForEachUsage {public static void main(String[] args) {Stream<Integer> ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> result = new ArrayList<>();CustomForEach.forEach(ints, (elem, breaker) -> {if (elem >= 5 ) {breaker.stop();} else {result.add(elem);}});log.info(result.toString());} }上面我們用新的forEach方法,并通過判斷條件來重置判斷flag,從而達到break stream的目的。
總結
本文通過兩個具體的例子講解了如何break一個stream,希望大家能夠喜歡。
本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/break-stream-foreach
更多精彩內容且看:
- 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
- java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程
歡迎關注我的公眾號:程序那些事,更多精彩等著您!
更多內容請訪問 www.flydean.com
總結
以上是生活随笔為你收集整理的怎么break java8 stream的foreach的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 8 stream中的Split
- 下一篇: JDK 15 JAVA 15的新特性展望