计算素数(流和lambda)
我编写了以下代码来获取2..n中的所有素数计算素数(流和lambda),lambda,java-8,java-stream,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 ||
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和streams的练习
但是现在我想通过存储所有以前发现的素数来进一步优化它
因为这需要将这些值存储在流管道的中间,也就是中间操作,并且大多数流中间操作应该是无状态的,根据它们的文档,您试图在这里使用错误的工具来执行任务。 有状态ops可以通过提取流的
拆分器来实现,将其包装成一个自定义的拆分器并重新包装成一个新的流,但在这种情况下,考虑到这基本上就是流管道所做的一切,这似乎并不合适
由于您正试图运行一个有状态且可并行化的计算任务,因此您可能需要查看or。前者也被用作并行流实现的一部分,后者使计算及其结果更容易组合。试试这个
public static boolean isPrime(final long number) {
return LongStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0);
}
我有几乎相同的任务要解决,我创建了下一个完美工作的代码:
public static int[] primes(int n) {
return IntStream.rangeClosed(2, n)
.filter(p -> BigInteger.valueOf(p).isProbablePrime(50)).toArray();
}
有了这个,你可以用建立的素数除以这些数字进行过滤。我认为更好的优化方法是(a)将noneMatch()改为anyMatch(),并对结果求反(b)你的过滤操作实际上非常局限于检查数字是否在2..sqrt(输入)之间可被2整除,不检查其他素数,如3,5。。。。与所有这些步骤不同的是,当数字被2,3,4,5整除时,流就会返回。@Baski:为什么你认为从noneMatch()
更改为anyMatch()
并否定结果会优化任何东西?如果你想以内存为代价优化速度,使用位集
对埃拉托斯坦进行筛选。但是,由于这是streams中的一个练习,您可以在isPrime
中使用getPrimesStream
来获取要测试的素因子:returnnumber==2 | | getPrimesStream((long)ceil(sqrt(number))。非匹配(除数->number%除数==0)
@Misha:在这种情况下,如果isPrime
测试0
和1
(或者简单地说,@Holger谢谢你捕捉到了错误信息。我想我可能是被精神障碍束缚了,没有完全阅读API文档。我可以知道为什么数字+1吗?@JigarNaik我可能是错的。我这么做只是为了避免舍入错误。为什么不调用noneMatch()而不是anyMatch())还有一个否定符号?@JeanneBoyarsky谢谢你的帖子。我已经更新了我的例子
public static int[] primes(int n) {
return IntStream.rangeClosed(2, n)
.filter(p -> BigInteger.valueOf(p).isProbablePrime(50)).toArray();
}