Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calculating prime numbers (streams and lambdas)

I wrote the following code to get all the prime numbers from 2..n

private static LongStream getPrimesStream(long number) {
    return LongStream.range(2, number + 1)
            .filter(PrimeStreamTest::isPrime);
}

private static boolean isPrime(final long number) {
    return number == 2 || (number % 2 != 0 && LongStream
            .range(2, (long) Math.ceil(Math.sqrt(number + 1)))
            .filter(n -> n % 2 != 0)
            .noneMatch(divisor -> number % divisor == 0)
    );
}

I optimized it by checking in the range of 2..sqrt(n) and filtering out the even numbers, but now I want to further optimize it by storing all previously found primes (I don't care about memory), so that I can filter out the numbers divisible by those primes, and not just the ones divisible by 2. I know there are better solutions, but it's just an exercise on lambdas and streams.

like image 512
CCC Avatar asked Jun 14 '16 01:06

CCC


2 Answers

but now I want to further optimize it by storing all previously found primes

Since that would require storing those values in the middle of the stream pipeline, i.e. be an intermediate operation and most stream intermediate operations should be stateless according to their docs you're trying to use the wrong tool for the job here.

Stateful ops can be implemented by extracting a stream's Spliterator, wrapping it into a custom one and rewrapping it into a new stream, but in this case that seems hardly appropriate considering that this would essentially be all what your stream pipeline does.

Since you're trying to run a stateful and parallelizable compute task you might want to look into the fork-join framework or CompletableFuture instead. The former is also used as part of the parallel stream implementation and the latter make it easier to compose computations and their results.

like image 152
the8472 Avatar answered Nov 11 '22 09:11

the8472


try this

public static boolean isPrime(final long number) {
   return LongStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0);
}
like image 1
dehasi Avatar answered Nov 11 '22 08:11

dehasi