diff --git a/core-java-modules/core-java-streams-4/pom.xml b/core-java-modules/core-java-streams-4/pom.xml
index 110ec50b8c..8c4d98979c 100644
--- a/core-java-modules/core-java-streams-4/pom.xml
+++ b/core-java-modules/core-java-streams-4/pom.xml
@@ -15,6 +15,16 @@
+
+ io.reactivex
+ rxjava
+ ${rx.java.version}
+
+
+ io.reactivex.rxjava2
+ rxjava
+ ${rx.java2.version}
+
log4j
log4j
@@ -27,6 +37,13 @@
pom
import
+
+ org.assertj
+ assertj-core
+ 3.23.1
+ test
+
+
@@ -54,8 +71,10 @@
3.1
- 1.8
- 1.8
+ 12
+ 12
+ 1.2.5
+ 2.2.2
\ No newline at end of file
diff --git a/core-java-modules/core-java-streams-4/src/test/java/splitting/Article.java b/core-java-modules/core-java-streams-4/src/test/java/splitting/Article.java
new file mode 100644
index 0000000000..fe1265df19
--- /dev/null
+++ b/core-java-modules/core-java-streams-4/src/test/java/splitting/Article.java
@@ -0,0 +1,37 @@
+package splitting;
+
+class Article {
+ private final String target;
+ private final boolean featured;
+
+ public Article(String target, boolean featured) {
+ this.target = target;
+ this.featured = featured;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public boolean isFeatured() {
+ return featured;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Article article = (Article) o;
+
+ if (featured != article.featured) return false;
+ return target.equals(article.target);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = target.hashCode();
+ result = 31 * result + (featured ? 1 : 0);
+ return result;
+ }
+}
diff --git a/core-java-modules/core-java-streams-4/src/test/java/splitting/StreamSplittingUnitTest.java b/core-java-modules/core-java-streams-4/src/test/java/splitting/StreamSplittingUnitTest.java
new file mode 100644
index 0000000000..75c60af4ac
--- /dev/null
+++ b/core-java-modules/core-java-streams-4/src/test/java/splitting/StreamSplittingUnitTest.java
@@ -0,0 +1,95 @@
+package splitting;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import rx.Observable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class StreamSplittingUnitTest {
+ private final static List articles = Lists.newArrayList(
+ new Article("Baeldung", true),
+ new Article("Baeldung", false),
+ new Article("Programming Daily", false),
+ new Article("The Code", false)
+ );
+
+ @Test
+ public void givenListOfArticles_shouldSplitListInTwoCategories_usingPartitioningBy() {
+ Map> groupedArticles = articles.stream().collect(Collectors.partitioningBy(a -> a.getTarget().equals("Baeldung")));
+
+ assertThat(groupedArticles.get(true)).containsExactly(
+ new Article("Baeldung", true),
+ new Article("Baeldung", false));
+ assertThat(groupedArticles.get(false)).containsExactly(
+ new Article("Programming Daily", false),
+ new Article("The Code", false));
+ }
+
+ @Test
+ public void givenListOfArticles_shouldSplitListInMultipleCategories_usingGroupingBy() {
+ Map> groupedArticles = articles.stream().collect(Collectors.groupingBy(Article::getTarget));
+
+ assertThat(groupedArticles.get("Baeldung")).hasSize(2);
+ assertThat(groupedArticles.get("Programming Daily")).hasSize(1);
+ assertThat(groupedArticles.get("The Code")).hasSize(1);
+
+ assertThat(groupedArticles.get("Baeldung")).containsExactly(
+ new Article("Baeldung", true),
+ new Article("Baeldung", false));
+ assertThat(groupedArticles.get("Programming Daily")).containsExactly(new Article("Programming Daily", false));
+ assertThat(groupedArticles.get("The Code")).containsExactly(new Article("The Code", false));
+ }
+
+ @Test
+ public void givenListOfArticles_shouldSplitListInTwoCategories_usingTeeing() {
+ List countedArticles = articles.stream().collect(Collectors.teeing(
+ Collectors.filtering(article -> article.getTarget().equals("Baeldung"), Collectors.counting()),
+ Collectors.filtering(article -> !article.getTarget().equals("Baeldung"), Collectors.counting()),
+ List::of));
+
+ assertThat(countedArticles.get(0)).isEqualTo(2);
+ assertThat(countedArticles.get(1)).isEqualTo(2);
+ }
+
+ @Test
+ public void givenListOfArticles_shouldSplitListInTwoOVerlappingCategories_usingTeeing() {
+ List> groupedArticles = articles.stream().collect(Collectors.teeing(
+ Collectors.filtering(article -> article.getTarget().equals("Baeldung"), Collectors.toList()),
+ Collectors.filtering(Article::isFeatured, Collectors.toList()),
+ List::of));
+
+ assertThat(groupedArticles.get(0)).hasSize(2);
+ assertThat(groupedArticles.get(1)).hasSize(1);
+
+ assertThat(groupedArticles.get(0)).containsExactly(
+ new Article("Baeldung", true),
+ new Article("Baeldung", false));
+ assertThat(groupedArticles.get(1)).containsExactly(new Article("Baeldung", true));
+ }
+
+ @Test
+ public void givenListOfArticles_shouldSplitStreamInMultipleCategories_usingRxJava() {
+ Observable observableArticles = Observable.from(articles);
+
+ Observable baeldungObservable = observableArticles.filter(article -> article.getTarget().equals("Baeldung"));
+ Observable featuredObservable = observableArticles.filter(Article::isFeatured);
+ List baeldungArticles = new ArrayList<>();
+ List featuredArticles = new ArrayList<>();
+ baeldungObservable.subscribe(baeldungArticles::add);
+ featuredObservable.subscribe(featuredArticles::add);
+
+ assertThat(baeldungArticles).hasSize(2);
+ assertThat(featuredArticles).hasSize(1);
+
+ assertThat(baeldungArticles).containsExactly(
+ new Article("Baeldung", true),
+ new Article("Baeldung", false));
+ assertThat(featuredArticles).containsExactly(new Article("Baeldung", true));
+ }
+}
diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml
index e44c508ce2..6911ace6eb 100644
--- a/core-java-modules/pom.xml
+++ b/core-java-modules/pom.xml
@@ -115,7 +115,6 @@
core-java-streams
core-java-streams-2
core-java-streams-3
- core-java-streams-4
core-java-string-algorithms
core-java-string-algorithms-2
core-java-string-apis
@@ -147,4 +146,4 @@
-
\ No newline at end of file
+
diff --git a/pom.xml b/pom.xml
index 912a13f402..0801fbab46 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1238,6 +1238,7 @@
core-java-modules/core-java-io-conversions-2
core-java-modules/core-java-jpms
core-java-modules/core-java-os
+ core-java-modules/core-java-streams-4
core-java-modules/core-java-string-algorithms-3
core-java-modules/core-java-string-operations-3
core-java-modules/core-java-string-operations-4