我正在阅读破解编码面试,其中有一个示例,该示例可以找到我在JShell上运行的素数
boolean isPrime(int n) {
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
然后我试图将其转换为java中的流,但是发现存在上述困难
boolean isPrimeStream(int n) {
return IntStream.range(0, n) // how to do similar to for loop above
.anyMatch(i -> n % i == 0); // i think this is the reason for failure
}
答案 0 :(得分:4)
问题一,您应该使用noneMatch
(而不是anyMatch
)。问题二,您的范围不对。使用rangeClosed
(或在末尾添加一个),该值应为n
的平方根(而不仅仅是n
)-在第一个测试中,您以2作为初始值。另外,您也可以使用方法static
。喜欢,
static boolean isPrimeStream(int n) {
return IntStream.rangeClosed(2, (int) Math.sqrt(n))
.noneMatch(i -> n % i == 0);
}
此外,我们可以通过处理2
作为特例来改进您的第一个示例。这样一来,您可以从3开始,然后以2为增量,跳过所有偶数值。
static boolean isPrime(int n) {
if (n == 2) {
return true;
} else if (n % 2 == 0) {
return false;
}
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
答案 1 :(得分:3)
您应该在此处使用IntStream.noneMatch
:
boolean isPrimeStream(int n) {
return IntStream.range(2, n) // note division by zero possible in your attempt
.noneMatch(i -> n % i == 0);
}
编辑 :正如Andreas的评论所指出的那样,使用range(2, n)
避免被零除,因为除以1总是会导致条件为真并返回否则为false
的结果。
返回此流的 无元素 是否与提供的 谓词
您当前的代码正在使用IntStream.anyMatch
返回此流的 任何元素 是否与提供的 谓词
这就是为什么如果任何输入都满足指定条件的情况,而不是方法应返回true
的情况下,它将返回false
的原因。
与上面的for循环类似的操作方式
使用java-9或更高版本,您可以将IntStrem.iterate
用作
private boolean isPrimeStream(int n) {
return IntStream.iterate(2, i -> i * i <= n, i -> i + 1) // similar to the loop
.noneMatch(i -> n % i == 0);
}
答案 2 :(得分:2)
使用Java8流完成此任务的意义是什么?对我而言,您正在重新发明轮子。这一条衬里就足够了。
BigInteger.valueOf(n).isProbablePrime(50);
还要注意,使用流可以更好地解决一些问题。但这并不意味着流是解决所有问题的灵丹妙药。
这是文档中有关确定性的摘录。
对于一个大的已知质数,并且对于> 0的任何确定性, 说b.isProbablePrime(certainty)将始终返回true。