I am learning streams and lambdas in Java 8.
I wanted to implement the classic Sieve of Eratosthenes using lambdas and streams. This is my implementation.
/**
* @author Sanjay
*/
class Sieve {
/**
* Implementation of Sieve of eratosthenes algorithm using streams and lambdas
* It's much slower than the version with traditional for loops
* It consumes much memory than the version with traditional for loops
* It computes all primes upto 100_000_000 in 2 secs (approx)
*/
public static List<Integer> sieveOfEratosthenes(int _n) {
// if _n is empty return an empty list
if (_n <= 1) return Arrays.asList();
// create a boolean array each index representing index number itself
boolean[] prime = new boolean[_n + 1];
// set all the values in prime as true
IntStream.rangeClosed(0, _n).forEach(x -> prime[x] = true);
// make all composite numbers false in prime array
IntStream.rangeClosed(2, (int) Math.sqrt(_n))
.filter(x -> prime[x])
.forEach(x -> unsetFactors(x, prime, _n));
// create a list containing primes upto _n
List<Integer> primeList = new ArrayList<>((_n < 20) ? _n : (_n < 100) ? 30 : _n / 3);
// add all the indexes that represent true in prime array to primeList
IntStream.rangeClosed(2, _n).filter(x -> prime[x]).forEach(primeList::add);
// return prime list
return primeList;
}
/*
* makes all the factors of x in prime array to false
* as primes don't have any factors
* here x is a prime and this makes all factors of x as false
*/
private static void unsetFactors(int x, boolean[] prime, int _n) {
IntStream.iterate(x * 2, factor -> factor + x)
.limit(_n / x - 1)
.forEach(factor -> prime[factor] = false);
}
}
What is its efficiency compared to normal for-loops? Are there any imporvements to be made?