计算素数(溪流和羔羊)

时间:2016-06-14 01:27:29

标签: lambda java-8 java-stream

我编写了以下代码来获取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)
    );
}

我通过检查2..sqrt(n)的范围并滤除偶数来优化它,但现在我想通过存储所有以前找到的素数(我不关心内存)来进一步优化它,这样我就可以过滤掉那些可以被这些素数整除的数字,而不仅仅是可被2整除的数字。 我知道有更好的解决方案,但这只是对lambdas和溪流的练习。

4 个答案:

答案 0 :(得分:3)

  

但现在我想通过存储所有以前找到的素数来进一步优化它

因为那需要将这些值存储在流管道的中间,即是一个中间操作,并且大多数流中间操作应根据他们的文档无状态,你试图在这里使用错误的工具

有状态操作可以通过提取流Spliterator,将其包装到自定义的流中并将其重新包装到新流中来实现,但在这种情况下,考虑到这基本上是你的流管道所做的一切。

由于您尝试运行有状态且可并行化的计算任务,因此您可能需要查看fork-join frameworkCompletableFuture。前者也用作并行流实现的一部分,后者使组合计算及其结果更容易。

答案 1 :(得分:1)

试试这个

public static boolean isPrime(final long number) {
   return LongStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0);
}

答案 2 :(得分:0)

// check if number return true when it divided by it self and one only
IntPredicate isDivisible = index -> number % index == 0;
// test the number 
isDivisible.test(number);
// check if numbers between 2 and the provided number is prime 
return IntStream.range(2, number - 1).noneMatch(isDivisible);

答案 3 :(得分:0)

我要完成几乎相同的任务,然后创建下一个代码,可以正常工作:

public static int[] primes(int n) {
    return IntStream.rangeClosed(2, n)
        .filter(p -> BigInteger.valueOf(p).isProbablePrime(50)).toArray();
}

通过此操作,您可以通过将数字除以已建立的质数来进行过滤。