Esempi sugli stream paralleli
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
package org.gym.fp.moderjava;
|
||||||
|
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
|
||||||
|
public class ForkJoinSumCalculator extends RecursiveTask<Long> {
|
||||||
|
public static final long THRESHOLD = 10_000;
|
||||||
|
|
||||||
|
private final long[] numbers;
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
public ForkJoinSumCalculator(long[] numbers) {
|
||||||
|
this(numbers, 0, numbers.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ForkJoinSumCalculator(long[] numbers, int start, int end) {
|
||||||
|
this.numbers = numbers;
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Long compute() {
|
||||||
|
int length = end - start;
|
||||||
|
if (length <= THRESHOLD) {
|
||||||
|
return computeSequentially();
|
||||||
|
}
|
||||||
|
ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length / 2);
|
||||||
|
leftTask.fork();
|
||||||
|
ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length / 2, end);
|
||||||
|
Long rightResult = rightTask.compute();
|
||||||
|
Long leftResult = leftTask.join();
|
||||||
|
return leftResult + rightResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long computeSequentially() {
|
||||||
|
long sum = 0;
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
sum += numbers[i];
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
package org.gym.fp.moderjava;
|
package org.gym.fp.moderjava;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.LongStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import static java.lang.System.out;
|
import static java.lang.System.out;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
@@ -10,6 +14,10 @@ import static java.util.Comparator.comparingInt;
|
|||||||
import static java.util.stream.Collectors.*;
|
import static java.util.stream.Collectors.*;
|
||||||
|
|
||||||
public class StreamTest {
|
public class StreamTest {
|
||||||
|
private static final String SENTENCE =
|
||||||
|
" Nel mezzo del cammin di nostra vita " +
|
||||||
|
"mi ritrovia in una selva oscura" +
|
||||||
|
" ché la dritta via era smarrita ";
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
doStreamFilterDemo();
|
doStreamFilterDemo();
|
||||||
@@ -17,6 +25,7 @@ public class StreamTest {
|
|||||||
doStreamFindOrMatchingDemo();
|
doStreamFindOrMatchingDemo();
|
||||||
doStreamReducingDemo();
|
doStreamReducingDemo();
|
||||||
doStreamCollectingDemo();
|
doStreamCollectingDemo();
|
||||||
|
doStreamParallelDemo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doStreamFilterDemo() {
|
private static void doStreamFilterDemo() {
|
||||||
@@ -302,6 +311,31 @@ public class StreamTest {
|
|||||||
out.println("----------------------------------------");
|
out.println("----------------------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void doStreamParallelDemo() {
|
||||||
|
out.println("ForkJoin result (1, 100) = " + forkJoinSum(100));
|
||||||
|
out.println("----------------------------------------");
|
||||||
|
Stream<Character> stream1 = IntStream.range(0, SENTENCE.length()).mapToObj(SENTENCE::charAt);
|
||||||
|
out.printf("Found %d words\n", countWords(stream1));
|
||||||
|
out.println("----------------------------------------");
|
||||||
|
Spliterator<Character> spliterator = new WordCounterSpliterator(SENTENCE);
|
||||||
|
Stream<Character> stream2 = StreamSupport.stream(spliterator, true);
|
||||||
|
out.printf("Found %d words\n", countWords(stream2));
|
||||||
|
out.println("----------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int countWords(Stream<Character> stream) {
|
||||||
|
WordCounter wordCounter = stream.reduce(new WordCounter(0, true),
|
||||||
|
WordCounter::accumulate,
|
||||||
|
WordCounter::combine);
|
||||||
|
return wordCounter.getCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long forkJoinSum(int n) {
|
||||||
|
long[] numbers = LongStream.rangeClosed(1, n).toArray();
|
||||||
|
ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
|
||||||
|
return new ForkJoinPool().invoke(task);
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<Boolean, List<Integer>> partitionPrimes(int n) {
|
public static Map<Boolean, List<Integer>> partitionPrimes(int n) {
|
||||||
return IntStream.rangeClosed(2, n).boxed()
|
return IntStream.rangeClosed(2, n).boxed()
|
||||||
.collect(partitioningBy(candidate -> isPrime(candidate)));
|
.collect(partitioningBy(candidate -> isPrime(candidate)));
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.gym.fp.moderjava;
|
||||||
|
|
||||||
|
public class WordCounter {
|
||||||
|
private final int counter;
|
||||||
|
private final boolean lastSpace;
|
||||||
|
|
||||||
|
public WordCounter(int counter, boolean lastSpace) {
|
||||||
|
this.counter = counter;
|
||||||
|
this.lastSpace = lastSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WordCounter accumulate(Character c) {
|
||||||
|
if (Character.isWhitespace(c)) return lastSpace ? this : new WordCounter(counter, true);
|
||||||
|
else return lastSpace ? new WordCounter(counter + 1, false) : this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WordCounter combine(WordCounter wordCounter) {
|
||||||
|
return new WordCounter(this.counter + wordCounter.getCounter(), wordCounter.lastSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package org.gym.fp.moderjava;
|
||||||
|
|
||||||
|
import java.util.Spliterator;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class WordCounterSpliterator implements Spliterator<Character> {
|
||||||
|
private final String string;
|
||||||
|
private int currentChar = 0;
|
||||||
|
|
||||||
|
public WordCounterSpliterator(String string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(Consumer<? super Character> action) {
|
||||||
|
action.accept(string.charAt(currentChar++));
|
||||||
|
return currentChar < string.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Spliterator<Character> trySplit() {
|
||||||
|
int currentSize = string.length() - currentChar;
|
||||||
|
if (currentSize < 10) return null;
|
||||||
|
for (int splitPos = currentSize / 2 + currentChar; splitPos < string.length(); splitPos++) {
|
||||||
|
if (Character.isWhitespace(string.charAt(splitPos))) {
|
||||||
|
Spliterator<Character> spliterator = new WordCounterSpliterator(
|
||||||
|
string.substring(currentChar, splitPos));
|
||||||
|
currentChar = splitPos;
|
||||||
|
return spliterator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long estimateSize() {
|
||||||
|
return string.length() - currentChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int characteristics() {
|
||||||
|
return ORDERED + SIZED + SUBSIZED + NONNULL + IMMUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user