讨论/《Java 实战(第 2 版)》 - 6.6.1 仅用质数做除数/
《Java 实战(第 2 版)》 - 6.6.1 仅用质数做除数
共 1 个回复

答案:你可以实现自己的takeWhile方法,它接受一个排序列表和一个谓词,返回列表元素中符合该谓词条件的最长子列表,代码如下所示:

public static <A> List<A> takeWhile(List<A> list, Predicate<A> p) {
int i = 0;
for (A item : list) {
        if (!p.test(item)) {       ←---- 检查列表中的当前元素是否符合谓词的约束
                return list.subList(0, i);       ←---- 如果当前元素不符合谓词要求,返回测试元素的前序子列表
        }
        i++;
}
return list;       ←---- 列表中的所有元素都符合该谓词时,返回该列表
}

采用这种方式,你可以重写isPrime方法,只对那些不大于其平方根的候选素数进行测试:

public static boolean isPrime(List<Integer> primes, int candidate){
int candidateRoot = (int) Math.sqrt((double) candidate);
return takeWhile(primes, i -> i <= candidateRoot)
            .stream()
            .noneMatch(p -> candidate % p == 0);
}

注意,与Stream API提供的版本不同,采用这种方式实现的版本是即时的。理想情况下,我们更希望采用Java 9那种由Stream提供的takeWhile,它具有延迟求值的特性,还能结合noneMatch来操作。