1.概述
Java Stream foreach 是一种声明式的,整洁的遍历循环。但是当我们满足某个条件想要中止这个循环的时候,通常却十分繁琐,比如使用异常,但通常这不是一种很好的实现方案
2.Java 9 Stream.takeWhile()
Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck")
.takeWhile(n - > n.length()%2 !=0)
.forEach(System.out::println)
运行结果
cat
dog
3.定制Spliterator
如果版本还是Java8的情况
首先,从我们的流中拿一个Spliterator,提供一个谓词Predicate 去控制break.
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 class CustomSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
private Spliterator<T> spliterator;
private Predicate<T> predicate;
private boolean isMatched = true;
public CustomSpliterator(Spliterator<T> spliterator, Predicate<T> predicate) {
super(spliterator.estimateSize(), 0);
this.spliterator = spliterator;
this.predicate = predicate;
}
@Override
public synchronized boolean tryAdvance(Consumer<? super T> consumer) {
boolean hadNext = spliterator.tryAdvance(element -> {
if(predicate.test(element) && isMatched){
consumer.accept(element);
}else{
isMatched = false;
}
});
return hadNext && isMatched;
}
}
写一个测试,只要Stream里面还有元素并且满足我们的谓词的条件就会中止
@Test
public void whenCustomTakeWhileIsCalled_ThenCorrectItemsAreReturned(){
Stream<String> initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
List<String> result = CustomTakeWhile.takeWhile(initialStream, x -> x.length() % 2 != 0).collect(Collectors.toList());
assertEquals(asList("cat", "dog"),result);
}
4.定制ForEach
不对Stream.spliterator进行包装的方法
public class CustomForEach {
public static class Breaker{
private 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(element -> {
consumer.accept(element, breaker);
});
}
}
}
@Test
public void whenCustomTakeWhileIsCalled_ThenCorrectItemsAreReturned2(){
Stream<String> initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
List<String> result = new ArrayList<>();
CustomForEach.forEach(initialStream,(element,breaker)->{
if(element.length() % 2 == 0){
breaker.stop();
} else{
result.add(element);
}
});
assertEquals(asList("cat", "dog"),result);
}
标签:predicate,Java,Stream,spliterator,element,boolean,forEach,public
From: https://www.cnblogs.com/metatreasure/p/17177960.html