added break mechanisms for Stream.forEach (#7053)

This commit is contained in:
Catalin Burcea 2019-06-25 15:50:22 +03:00 committed by ashleyfrieze
parent 8470ca7c5b
commit 3e4607e724
7 changed files with 148 additions and 4 deletions

View File

@ -4,7 +4,7 @@
<groupId>com.baeldung.javastreams2</groupId>
<artifactId>javastreams2</artifactId>
<version>1.0</version>
<name>Stream Reduce</name>
<name>javastreams2</name>
<packaging>jar</packaging>
<parent>
@ -42,8 +42,8 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
<assertj.version>3.11.1</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,32 @@
package com.baeldung.breakforeach;
import java.util.Spliterator;
import java.util.function.BiConsumer;
import java.util.stream.Stream;
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(elem -> {
consumer.accept(elem, breaker);
});
}
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.breakforeach;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class CustomSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
private Spliterator<T> splitr;
private Predicate<T> predicate;
private boolean isMatched = true;
public CustomSpliterator(Spliterator<T> splitr, Predicate<T> predicate) {
super(splitr.estimateSize(), 0);
this.splitr = splitr;
this.predicate = predicate;
}
@Override
public 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;
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.breakforeach;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class CustomTakeWhile {
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);
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.breakforeach;
import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
public class TakeWhileExample {
public static void takeWhileJava9() {
Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck")
.takeWhile(n -> n.length() % 2 != 0)
.forEach(System.out::println); // cat, dog
}
public static void plainForLoopWithBreak() {
List<String> list = asList("cat", "dog", "elephant", "fox", "rabbit", "duck");
for (int i = 0; i < list.size(); i++) {
String item = list.get(i);
if (item.length() % 2 == 0) {
break;
}
System.out.println(item);
}
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.breakforeach;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
public class BreakFromStreamForEachUnitTest {
@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);
}
@Test
public void whenCustomForEachIsCalled_ThenCorrectItemsAreReturned() {
Stream<String> initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
List<String> result = new ArrayList<>();
CustomForEach.forEach(initialStream, (elem, breaker) -> {
if (elem.length() % 2 == 0) {
breaker.stop();
} else {
result.add(elem);
}
});
assertEquals(asList("cat", "dog"), result);
}
}

View File

@ -464,7 +464,7 @@
<module>java-rmi</module>
<module>java-spi</module>
<module>java-streams</module>
<module>java-streams-2</module>
<!-- <module>java-streams-2</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 -->
<module>java-strings</module>
<module>java-strings-2</module>
<module>java-vavr-stream</module>