added break mechanisms for Stream.forEach (#7053)
This commit is contained in:
parent
8470ca7c5b
commit
3e4607e724
|
@ -4,7 +4,7 @@
|
||||||
<groupId>com.baeldung.javastreams2</groupId>
|
<groupId>com.baeldung.javastreams2</groupId>
|
||||||
<artifactId>javastreams2</artifactId>
|
<artifactId>javastreams2</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
<name>Stream Reduce</name>
|
<name>javastreams2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
@ -42,8 +42,8 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.9</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.9</maven.compiler.target>
|
||||||
<assertj.version>3.11.1</assertj.version>
|
<assertj.version>3.11.1</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2
pom.xml
2
pom.xml
|
@ -464,7 +464,7 @@
|
||||||
<module>java-rmi</module>
|
<module>java-rmi</module>
|
||||||
<module>java-spi</module>
|
<module>java-spi</module>
|
||||||
<module>java-streams</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</module>
|
||||||
<module>java-strings-2</module>
|
<module>java-strings-2</module>
|
||||||
<module>java-vavr-stream</module>
|
<module>java-vavr-stream</module>
|
||||||
|
|
Loading…
Reference in New Issue