diff --git a/java-streams-2/pom.xml b/java-streams-2/pom.xml
index 3e08e2f432..f7a0379ac5 100644
--- a/java-streams-2/pom.xml
+++ b/java-streams-2/pom.xml
@@ -4,7 +4,7 @@
com.baeldung.javastreams2
javastreams2
1.0
- Stream Reduce
+ javastreams2
jar
@@ -42,8 +42,8 @@
UTF-8
- 1.8
- 1.8
+ 1.9
+ 1.9
3.11.1
\ No newline at end of file
diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomForEach.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomForEach.java
new file mode 100644
index 0000000000..1f8866b16c
--- /dev/null
+++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomForEach.java
@@ -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 void forEach(Stream stream, BiConsumer consumer) {
+ Spliterator spliterator = stream.spliterator();
+ boolean hadNext = true;
+ Breaker breaker = new Breaker();
+
+ while (hadNext && !breaker.get()) {
+ hadNext = spliterator.tryAdvance(elem -> {
+ consumer.accept(elem, breaker);
+ });
+ }
+ }
+}
diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomSpliterator.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomSpliterator.java
new file mode 100644
index 0000000000..cfe4bedac3
--- /dev/null
+++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomSpliterator.java
@@ -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 extends Spliterators.AbstractSpliterator {
+
+ private Spliterator splitr;
+ private Predicate predicate;
+ private boolean isMatched = true;
+
+ public CustomSpliterator(Spliterator splitr, Predicate 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;
+ }
+}
\ No newline at end of file
diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomTakeWhile.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomTakeWhile.java
new file mode 100644
index 0000000000..05574f9ae6
--- /dev/null
+++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomTakeWhile.java
@@ -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 Stream takeWhile(Stream stream, Predicate predicate) {
+ CustomSpliterator customSpliterator = new CustomSpliterator<>(stream.spliterator(), predicate);
+ return StreamSupport.stream(customSpliterator, false);
+ }
+
+}
diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/TakeWhileExample.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/TakeWhileExample.java
new file mode 100644
index 0000000000..1838ae5fb7
--- /dev/null
+++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/TakeWhileExample.java
@@ -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 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/java-streams-2/src/test/java/com/baeldung/breakforeach/BreakFromStreamForEachUnitTest.java b/java-streams-2/src/test/java/com/baeldung/breakforeach/BreakFromStreamForEachUnitTest.java
new file mode 100644
index 0000000000..23653c0a39
--- /dev/null
+++ b/java-streams-2/src/test/java/com/baeldung/breakforeach/BreakFromStreamForEachUnitTest.java
@@ -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 initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
+
+ List result = CustomTakeWhile.takeWhile(initialStream, x -> x.length() % 2 != 0)
+ .collect(Collectors.toList());
+
+ assertEquals(asList("cat", "dog"), result);
+ }
+
+ @Test
+ public void whenCustomForEachIsCalled_ThenCorrectItemsAreReturned() {
+ Stream initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
+ List result = new ArrayList<>();
+
+ CustomForEach.forEach(initialStream, (elem, breaker) -> {
+ if (elem.length() % 2 == 0) {
+ breaker.stop();
+ } else {
+ result.add(elem);
+ }
+ });
+
+ assertEquals(asList("cat", "dog"), result);
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 9760e06bc1..982c52c54e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -464,7 +464,7 @@
java-rmi
java-spi
java-streams
- java-streams-2
+
java-strings
java-strings-2
java-vavr-stream