Skip to content

Instantly share code, notes, and snippets.

@wcang
Created April 25, 2022 12:00
Show Gist options
  • Select an option

  • Save wcang/6a81704eaa9bc4b54d686a313a9dae97 to your computer and use it in GitHub Desktop.

Select an option

Save wcang/6a81704eaa9bc4b54d686a313a9dae97 to your computer and use it in GitHub Desktop.
PrimeNumberCollector that collects prime numbers into a list from an Integer stream. OptimizedPrimeNumberCollector is an optimized version of the collector using the accumulated list of prior prime numbers to weed out a prime number candidate. Refers to Java 8 In Action for details
package com.wcang;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
Instant start, stop;
start = Instant.now();
List<Integer> primes = (IntStream.rangeClosed(0, 10000000)).parallel().boxed().filter(PrimeNumberCollector::isPrime).collect(Collectors.toList());
stop = Instant.now();
long timeElapsed = Duration.between(start, stop).toMillis();
System.out.println(primes);
start = Instant.now();
List<Integer> optimizedPrimes = IntStream.rangeClosed(0, 10000000).boxed().collect(new OptimizedPrimeNumberCollector());
stop = Instant.now();
long timeOptimizedElapsed = Duration.between(start, stop).toMillis();
System.out.println(optimizedPrimes);
System.out.printf("Optimized and unoptimized prime numbers %s\n", primes.equals(optimizedPrimes) ? "matches" : "doesn't match");
System.out.printf("Optimized elapsed time %d ms unoptimized elapsed time %d ms\n", timeOptimizedElapsed, timeElapsed);
}
}
package com.wcang;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.IntStream;
public class OptimizedPrimeNumberCollector extends PrimeNumberCollector {
/* this assumes that the list of primes has already covered prior prime number is looked through serially
what if the stream is handled in parallel and some of the prime number is not added in advanced. I
supposed when Characteristics.UNORDERED is omitted, this scenario will not happen
*/
public static boolean isPrime(List<Integer> primes, int candidate) {
if (candidate < 2)
return false;
int candidateRoot = (int) Math.sqrt(candidate);
return primes.stream().takeWhile(num -> num <= candidateRoot)
.noneMatch(num -> candidate % num == 0);
}
@Override
public BiConsumer<List<Integer>, Integer> accumulator() {
return (acc, num) -> {
if (isPrime(acc, num)) {
acc.add(num);
}
};
}
}
package com.wcang;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.IntStream;
public class PrimeNumberCollector implements Collector<Integer, List<Integer>, List<Integer>> {
@Override
public Supplier<List<Integer>> supplier() {
return ArrayList::new;
}
public static boolean isPrime(int candidate) {
if (candidate < 2)
return false;
int candidateRoot = (int) Math.sqrt(candidate);
return IntStream.rangeClosed(2, candidateRoot)
.noneMatch(num -> candidate % num == 0);
}
@Override
public BiConsumer<List<Integer>, Integer> accumulator() {
return (acc, num) -> {
if (isPrime(num)) {
acc.add(num);
}
};
}
@Override
public BinaryOperator<List<Integer>> combiner() {
return (acc1, acc2) -> {
acc1.addAll(acc2);
return acc1;
};
}
@Override
public Function<List<Integer>, List<Integer>> finisher() {
return Function.identity();
}
@Override
public Set<Characteristics> characteristics() {
return Set.of(Characteristics.IDENTITY_FINISH);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment