BAEL-1473 Intoduction to Spliterator in Java (#3400)

This commit is contained in:
Ahmad Alsanie 2018-01-12 23:05:49 +02:00 committed by maibin
parent bff36974cd
commit 07aad444ae
6 changed files with 222 additions and 0 deletions

View File

@ -0,0 +1,44 @@
package com.baeldung.spliteratorAPI;
import java.util.List;
public class Article {
private List<Author> listOfAuthors;
private int id;
private String name;
public Article(String name) {
this.name = name;
}
public Article(List<Author> listOfAuthors, int id) {
super();
this.listOfAuthors = listOfAuthors;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Author> getListOfAuthors() {
return listOfAuthors;
}
public void setListOfAuthors(List<Author> listOfAuthors) {
this.listOfAuthors = listOfAuthors;
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.spliteratorAPI;
public class Author {
private String name;
private int relatedArticleId;
public Author(String name, int relatedArticleId) {
this.name = name;
this.relatedArticleId = relatedArticleId;
}
public int getRelatedArticleId() {
return relatedArticleId;
}
public void setRelatedArticleId(int relatedArticleId) {
this.relatedArticleId = relatedArticleId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "[name: " + name + ", relatedId: " + relatedArticleId + "]";
}
}

View File

@ -0,0 +1,45 @@
package com.baeldung.spliteratorAPI;
import java.util.Arrays;
import java.util.List;
import java.util.Spliterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Executor {
public void executeCustomSpliterator() {
Article article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1),
new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0),
new Author("Alice", 1), new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0);
Stream<Author> stream = IntStream.range(0, article.getListOfAuthors()
.size())
.mapToObj(article.getListOfAuthors()::get);
System.out.println("count= " + countAutors(stream.parallel()));
Spliterator<Author> spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors());
Stream<Author> stream2 = StreamSupport.stream(spliterator, true);
System.out.println("count= " + countAutors(stream2.parallel()));
}
public void executeSpliterator() {
Spliterator<Article> split1 = generateElements().spliterator();
Spliterator<Article> split2 = split1.trySplit();
ExecutorService service = Executors.newCachedThreadPool();
service.execute(new Task(split1));
service.execute(new Task(split2));
}
private static int countAutors(Stream<Author> stream) {
RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true), RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine);
return wordCounter.getCounter();
}
private List<Article> generateElements() {
return Stream.generate(() -> new Article("Java"))
.limit(35000)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.spliteratorAPI;
public class RelatedAuthorCounter {
private final int counter;
private final boolean isRelated;
public RelatedAuthorCounter(int counter, boolean isRelated) {
this.counter = counter;
this.isRelated = isRelated;
}
public RelatedAuthorCounter accumulate(Author author) {
if (author.getRelatedArticleId() == 0) {
return isRelated ? this : new RelatedAuthorCounter(counter, true);
} else {
return isRelated ? new RelatedAuthorCounter(counter + 1, false) : this;
}
}
public RelatedAuthorCounter combine(RelatedAuthorCounter RelatedAuthorCounter) {
return new RelatedAuthorCounter(counter + RelatedAuthorCounter.counter, RelatedAuthorCounter.isRelated);
}
public int getCounter() {
return counter;
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.spliteratorAPI;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
public class RelatedAuthorSpliterator implements Spliterator<Author> {
private final List<Author> list;
private int current = 0;
public RelatedAuthorSpliterator(List<Author> list) {
this.list = list;
}
@Override
public boolean tryAdvance(Consumer<? super Author> action) {
action.accept(list.get(current++));
return current < list.size();
}
@Override
public Spliterator<Author> trySplit() {
int currentSize = list.size() - current;
if (currentSize < 10) {
return null;
}
for (int splitPos = currentSize / 2 + current; splitPos < list.size(); splitPos++) {
if (list.get(splitPos)
.getRelatedArticleId() == 0) {
Spliterator<Author> spliterator = new RelatedAuthorSpliterator(list.subList(current, splitPos));
current = splitPos;
return spliterator;
}
}
return null;
}
@Override
public long estimateSize() {
return list.size() - current;
}
@Override
public int characteristics() {
return SIZED + CONCURRENT;
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.spliteratorAPI;
import java.util.Spliterator;
public class Task implements Runnable {
private Spliterator<Article> spliterator;
private final static String SUFFIX = "- published by Baeldung";
public Task(Spliterator<Article> spliterator) {
this.spliterator = spliterator;
}
@Override
public void run() {
int current = 0;
while (spliterator.tryAdvance(article -> {
article.setName(article.getName()
.concat(SUFFIX));
})) {
current++;
}
;
System.out.println(Thread.currentThread()
.getName() + ":" + current);
}
}