[JAVA-6173] stream.parallelStream and Collections parallel stream differences

This commit is contained in:
Bhaskar
2023-04-10 23:49:37 +05:30
parent acedc7f216
commit 48255ee387
6 changed files with 77 additions and 6 deletions

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-streams-5</artifactId>
<name>core-java-streams-5</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>${junit-jupiter.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.23.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>core-java-streams-4</finalName>
<resources>
<resource>
<directory>../core-java-streams-4/src/main</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<!-- testing -->
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
</project>

View File

@@ -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;
}
}

View File

@@ -0,0 +1,40 @@
package com.baeldung.streams.parallelstream;
import java.util.Spliterator;
import java.util.function.Consumer;
public class BookSpliterator<T> implements Spliterator<T> {
private final Object[] books;
private int startIndex;
public BookSpliterator(Object[] books, int startIndex) {
this.books = books;
this.startIndex = startIndex;
}
@Override
public Spliterator<T> 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<? super T> 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;
}
}

View File

@@ -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<T> implements Collection<T> {
private static final long serialVersionUID = 1L;
private T[] elements;
public MyBookContainer(T[] elements) {
this.elements = elements;
}
@Override
public Spliterator<T> spliterator() {
return new BookSpliterator(elements, 0);
}
@Override
public Stream<T> 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<T> iterator() {
return null;
}
@Override
public Object[] toArray() {
return new Object[0];
}
@Override
public <T1> 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<? extends T> c) {
return false;
}
@Override
public boolean removeAll(Collection<?> c) {
return false;
}
@Override
public boolean retainAll(Collection<?> c) {
return false;
}
@Override
public void clear() {
}
}

View File

@@ -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<Book> listOfbooks, int year) {
AtomicLong countOfBooks = new AtomicLong();
listOfbooks.parallelStream()
.forEach(book -> {
if (book.getYearPublished() == year) {
countOfBooks.getAndIncrement();
}
});
return countOfBooks.get();
}
public long usingStreamParallel(Collection<Book> 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<Book> listOfBooks, int year) {
AtomicLong countOfBooks = new AtomicLong();
listOfBooks.parallelStream()
.forEach(book -> {
if (book.getYearPublished() == year) {
countOfBooks.getAndIncrement();
}
});
return countOfBooks.get();
}
}

View File

@@ -0,0 +1,46 @@
package com.baeldung.parallelstream;
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<Book> 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<Book> books = List.of(book1, book2, book3);
return books;
}
private MyBookContainer<Book> getBookContainer() {
MyBookContainer<Book> 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;
}
}