Skip to content

Commit 07aad44

Browse files
gshell-techmaibin
authored andcommitted
BAEL-1473 Intoduction to Spliterator in Java (eugenp#3400)
1 parent bff3697 commit 07aad44

6 files changed

Lines changed: 222 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.baeldung.spliteratorAPI;
2+
3+
import java.util.List;
4+
5+
public class Article {
6+
private List<Author> listOfAuthors;
7+
private int id;
8+
private String name;
9+
10+
public Article(String name) {
11+
this.name = name;
12+
}
13+
14+
public Article(List<Author> listOfAuthors, int id) {
15+
super();
16+
this.listOfAuthors = listOfAuthors;
17+
this.id = id;
18+
}
19+
20+
public String getName() {
21+
return name;
22+
}
23+
24+
public void setName(String name) {
25+
this.name = name;
26+
}
27+
28+
public int getId() {
29+
return id;
30+
}
31+
32+
public void setId(int id) {
33+
this.id = id;
34+
}
35+
36+
public List<Author> getListOfAuthors() {
37+
return listOfAuthors;
38+
}
39+
40+
public void setListOfAuthors(List<Author> listOfAuthors) {
41+
this.listOfAuthors = listOfAuthors;
42+
}
43+
44+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.baeldung.spliteratorAPI;
2+
3+
public class Author {
4+
private String name;
5+
private int relatedArticleId;
6+
7+
public Author(String name, int relatedArticleId) {
8+
this.name = name;
9+
this.relatedArticleId = relatedArticleId;
10+
}
11+
12+
public int getRelatedArticleId() {
13+
return relatedArticleId;
14+
}
15+
16+
public void setRelatedArticleId(int relatedArticleId) {
17+
this.relatedArticleId = relatedArticleId;
18+
}
19+
20+
public String getName() {
21+
return name;
22+
}
23+
24+
public void setName(String name) {
25+
this.name = name;
26+
}
27+
28+
@Override
29+
public String toString() {
30+
return "[name: " + name + ", relatedId: " + relatedArticleId + "]";
31+
}
32+
}
33+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.baeldung.spliteratorAPI;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
import java.util.Spliterator;
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.Executors;
8+
import java.util.stream.Collectors;
9+
import java.util.stream.IntStream;
10+
import java.util.stream.Stream;
11+
import java.util.stream.StreamSupport;
12+
13+
public class Executor {
14+
public void executeCustomSpliterator() {
15+
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),
16+
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),
17+
new Author("Alice", 1), new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0);
18+
Stream<Author> stream = IntStream.range(0, article.getListOfAuthors()
19+
.size())
20+
.mapToObj(article.getListOfAuthors()::get);
21+
System.out.println("count= " + countAutors(stream.parallel()));
22+
Spliterator<Author> spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors());
23+
Stream<Author> stream2 = StreamSupport.stream(spliterator, true);
24+
System.out.println("count= " + countAutors(stream2.parallel()));
25+
}
26+
27+
public void executeSpliterator() {
28+
Spliterator<Article> split1 = generateElements().spliterator();
29+
Spliterator<Article> split2 = split1.trySplit();
30+
ExecutorService service = Executors.newCachedThreadPool();
31+
service.execute(new Task(split1));
32+
service.execute(new Task(split2));
33+
}
34+
35+
private static int countAutors(Stream<Author> stream) {
36+
RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true), RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine);
37+
return wordCounter.getCounter();
38+
}
39+
40+
private List<Article> generateElements() {
41+
return Stream.generate(() -> new Article("Java"))
42+
.limit(35000)
43+
.collect(Collectors.toList());
44+
}
45+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.baeldung.spliteratorAPI;
2+
3+
public class RelatedAuthorCounter {
4+
private final int counter;
5+
private final boolean isRelated;
6+
7+
public RelatedAuthorCounter(int counter, boolean isRelated) {
8+
this.counter = counter;
9+
this.isRelated = isRelated;
10+
}
11+
12+
public RelatedAuthorCounter accumulate(Author author) {
13+
if (author.getRelatedArticleId() == 0) {
14+
return isRelated ? this : new RelatedAuthorCounter(counter, true);
15+
} else {
16+
return isRelated ? new RelatedAuthorCounter(counter + 1, false) : this;
17+
}
18+
}
19+
20+
public RelatedAuthorCounter combine(RelatedAuthorCounter RelatedAuthorCounter) {
21+
return new RelatedAuthorCounter(counter + RelatedAuthorCounter.counter, RelatedAuthorCounter.isRelated);
22+
}
23+
24+
public int getCounter() {
25+
return counter;
26+
}
27+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.baeldung.spliteratorAPI;
2+
3+
import java.util.List;
4+
import java.util.Spliterator;
5+
import java.util.function.Consumer;
6+
7+
public class RelatedAuthorSpliterator implements Spliterator<Author> {
8+
private final List<Author> list;
9+
private int current = 0;
10+
11+
public RelatedAuthorSpliterator(List<Author> list) {
12+
this.list = list;
13+
}
14+
15+
@Override
16+
public boolean tryAdvance(Consumer<? super Author> action) {
17+
action.accept(list.get(current++));
18+
return current < list.size();
19+
}
20+
21+
@Override
22+
public Spliterator<Author> trySplit() {
23+
int currentSize = list.size() - current;
24+
if (currentSize < 10) {
25+
return null;
26+
}
27+
for (int splitPos = currentSize / 2 + current; splitPos < list.size(); splitPos++) {
28+
if (list.get(splitPos)
29+
.getRelatedArticleId() == 0) {
30+
Spliterator<Author> spliterator = new RelatedAuthorSpliterator(list.subList(current, splitPos));
31+
current = splitPos;
32+
return spliterator;
33+
}
34+
}
35+
return null;
36+
}
37+
38+
@Override
39+
public long estimateSize() {
40+
return list.size() - current;
41+
}
42+
43+
@Override
44+
public int characteristics() {
45+
return SIZED + CONCURRENT;
46+
}
47+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.baeldung.spliteratorAPI;
2+
3+
import java.util.Spliterator;
4+
5+
public class Task implements Runnable {
6+
private Spliterator<Article> spliterator;
7+
private final static String SUFFIX = "- published by Baeldung";
8+
9+
public Task(Spliterator<Article> spliterator) {
10+
this.spliterator = spliterator;
11+
}
12+
13+
@Override
14+
public void run() {
15+
int current = 0;
16+
while (spliterator.tryAdvance(article -> {
17+
article.setName(article.getName()
18+
.concat(SUFFIX));
19+
})) {
20+
current++;
21+
}
22+
;
23+
System.out.println(Thread.currentThread()
24+
.getName() + ":" + current);
25+
}
26+
}

0 commit comments

Comments
 (0)