From bde71a9dea2e0f3e755a43c1c8828ad00774bfdc Mon Sep 17 00:00:00 2001 From: Bhaskar Ghosh Dastidar Date: Fri, 24 Mar 2023 23:10:30 +0530 Subject: [PATCH] [JAVA-6173] Difference Between parallelStream() and stream().parallel() (#13653) * [JAVA-6173] stream.parallel and parallelStream * [JAVA-6173] stream.parallel and parallelStream test cases --------- Co-authored-by: Bhaskar --- .../baeldung/streams/parallelstream/Book.java | 37 ++++++++ .../parallelstream/BookSpliterator.java | 40 ++++++++ .../parallelstream/MyBookContainer.java | 93 +++++++++++++++++++ .../ParallelStreamApplication.java | 41 ++++++++ .../ParallelStreamUnitTest.java | 47 ++++++++++ 5 files changed, 258 insertions(+) create mode 100644 core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/Book.java create mode 100644 core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/BookSpliterator.java create mode 100644 core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/MyBookContainer.java create mode 100644 core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/ParallelStreamApplication.java create mode 100644 core-java-modules/core-java-streams-4/src/test/java/parallelstream/ParallelStreamUnitTest.java diff --git a/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/Book.java b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/Book.java new file mode 100644 index 0000000000..165df55166 --- /dev/null +++ b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/Book.java @@ -0,0 +1,37 @@ +package com.baeldung.streams.parallelstream; + +public class Book { + private String name; + private String author; + private int yearPublished; + + public Book(String name, String author, int yearPublished) { + this.name = name; + this.author = author; + this.yearPublished = yearPublished; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public int getYearPublished() { + return yearPublished; + } + + public void setYearPublished(int yearPublished) { + this.yearPublished = yearPublished; + } +} diff --git a/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/BookSpliterator.java b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/BookSpliterator.java new file mode 100644 index 0000000000..14e87e0b07 --- /dev/null +++ b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/BookSpliterator.java @@ -0,0 +1,40 @@ +package com.baeldung.streams.parallelstream; + +import java.util.Spliterator; +import java.util.function.Consumer; + +public class BookSpliterator implements Spliterator { + private final Object[] books; + private int startIndex; + public BookSpliterator(Object[] books, int startIndex) { + this.books = books; + this.startIndex = startIndex; + } + + @Override + public Spliterator trySplit() { + // Always Assuming that the source is too small to split, returning null + return null; + } + + // Other overridden methods such as tryAdvance(), estimateSize() etc + + @Override + public boolean tryAdvance(Consumer action) { + if (startIndex < books.length) { + startIndex += 2; + return true; + } + return false; + } + + @Override + public long estimateSize() { + return books.length - startIndex; + } + + @Override + public int characteristics() { + return CONCURRENT; + } +} diff --git a/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/MyBookContainer.java b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/MyBookContainer.java new file mode 100644 index 0000000000..dc4b0e2623 --- /dev/null +++ b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/MyBookContainer.java @@ -0,0 +1,93 @@ +package com.baeldung.streams.parallelstream; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class MyBookContainer implements Collection { + private static final long serialVersionUID = 1L; + private T[] elements; + + public MyBookContainer(T[] elements) { + this.elements = elements; + } + + @Override + public Spliterator spliterator() { + return new BookSpliterator(elements, 0); + } + + @Override + public Stream parallelStream() { + return StreamSupport.stream(spliterator(), false); + } + + // standard overridden methods of Collection Interface + + @Override + public int size() { + return elements.length; + } + + @Override + public boolean isEmpty() { + return elements.length == 0; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public Iterator iterator() { + return null; + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public T1[] toArray(T1[] a) { + return null; + } + + @Override + public boolean add(T t) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public boolean containsAll(Collection c) { + return false; + } + + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public void clear() { + + } +} diff --git a/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/ParallelStreamApplication.java b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/ParallelStreamApplication.java new file mode 100644 index 0000000000..9cdaf58bfb --- /dev/null +++ b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/parallelstream/ParallelStreamApplication.java @@ -0,0 +1,41 @@ +package com.baeldung.streams.parallelstream; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicLong; + +public class ParallelStreamApplication { + + public long usingCollectionsParallel(Collection listOfbooks, int year) { + AtomicLong countOfBooks = new AtomicLong(); + listOfbooks.parallelStream() + .forEach(book -> { + if (book.getYearPublished() == year) { + countOfBooks.getAndIncrement(); + } + }); + return countOfBooks.get(); + } + + public long usingStreamParallel(Collection listOfBooks, int year) { + AtomicLong countOfBooks = new AtomicLong(); + listOfBooks.stream() + .parallel() + .forEach(book -> { + if (book.getYearPublished() == year) { + countOfBooks.getAndIncrement(); + } + }); + return countOfBooks.get(); + } + + public long usingWithCustomSpliterator(MyBookContainer listOfBooks, int year) { + AtomicLong countOfBooks = new AtomicLong(); + listOfBooks.parallelStream() + .forEach(book -> { + if (book.getYearPublished() == year) { + countOfBooks.getAndIncrement(); + } + }); + return countOfBooks.get(); + } +} diff --git a/core-java-modules/core-java-streams-4/src/test/java/parallelstream/ParallelStreamUnitTest.java b/core-java-modules/core-java-streams-4/src/test/java/parallelstream/ParallelStreamUnitTest.java new file mode 100644 index 0000000000..5542a21020 --- /dev/null +++ b/core-java-modules/core-java-streams-4/src/test/java/parallelstream/ParallelStreamUnitTest.java @@ -0,0 +1,47 @@ +package parallelstream; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.streams.parallelstream.Book; +import com.baeldung.streams.parallelstream.MyBookContainer; +import com.baeldung.streams.parallelstream.ParallelStreamApplication; + +public class ParallelStreamUnitTest { + + @Test + public void givenCollectionWhenCollectionsParallelIsUsedThenReturnCount() { + ParallelStreamApplication parallelStreamApplication = new ParallelStreamApplication(); + Assert.assertEquals(parallelStreamApplication.usingCollectionsParallel(generateListOfBooks(), 1974), 2); + } + + @Test + public void givenCollectionWhenStreamParallelIsUsedThenReturnCount() { + ParallelStreamApplication parallelStreamApplication = new ParallelStreamApplication(); + Assert.assertEquals(parallelStreamApplication.usingStreamParallel(generateListOfBooks(), 1974), 2); + } + + @Test + public void givenBookContainerWhenParallelStreamIsUsedThenReturnIncorrectCount() { + ParallelStreamApplication parallelStreamApplication = new ParallelStreamApplication(); + Assert.assertNotEquals(parallelStreamApplication.usingWithCustomSpliterator(getBookContainer(), 1974), 2); + } + + private List generateListOfBooks() { + Book book1 = new Book("The Blue Umbrella", "Ruskin Bond", 1974); + Book book2 = new Book("Carrie", "Stephen King", 1974); + Book book3 = new Book("The Psychology of money", "Morgan Housel", 2020); + List books = List.of(book1, book2, book3); + return books; + } + + private MyBookContainer getBookContainer() { + MyBookContainer listOfBooks = new MyBookContainer<>(new Book[] { new Book("The Blue Umbrella", "Ruskin Bond", 1974), + new Book("Carrie", "Stephen King", 1974), + new Book("The Psychology of money", "Morgan Housel", 2020)}); + return listOfBooks; + } +}