[Java] 利用筛法生成质数流

58 阅读1分钟

利用筛法可以将质数筛选出来,如果将这一做法和 java 中的 Stream 结合起来,我们就会得到质数流。从理论上讲,我们可以通过筛法得到任意大的质数,但随着质数变大,筛法的效率会越来越低。

代码如下 ⬇️(请将其保存为 SimplePrimeNumberGenerator.java

import java.math.BigInteger;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class SimplePrimeNumberGenerator {
    // Please feel free to adjust the value of UPPER_BOUND
    // 请将 UPPER_BOUND 调整为您需要的值
    private static final BigInteger UPPER_BOUND = BigInteger.valueOf(100);

    public static void main(String[] args) {
        Predicate<BigInteger> isPrime = number -> {
            for (BigInteger factorCandidate = BigInteger.TWO;
                 factorCandidate.multiply(factorCandidate).compareTo(number) <= 0;
                 factorCandidate = factorCandidate.add(BigInteger.ONE)
            ) {
                if (number.mod(factorCandidate).equals(BigInteger.ZERO)) {
                    return false;
                }
            }
            return true;
        };

        Stream<BigInteger> primeNumberStream = Stream.iterate(BigInteger.TWO, previousPrime -> {
            BigInteger nextPrimeCandidate = previousPrime.add(BigInteger.ONE);
            while (!isPrime.test(nextPrimeCandidate)) {
                nextPrimeCandidate = nextPrimeCandidate.add(BigInteger.ONE);
            }
            return nextPrimeCandidate;
        });

        primeNumberStream.takeWhile(primeNumber -> primeNumber.compareTo(UPPER_BOUND) <= 0).forEach(System.out::println);
    }
}

用以下的命令可以编译和运行

javac SimplePrimeNumberGenerator.java
java SimplePrimeNumberGenerator

SimplePrimeNumberGenerator.java 可以找到所有小于等于 100100 的质数(如果调整代码第 9 行的 UPPER_BOUND 字段的值,则可以得到其他范围的质数,注意,请不要将其设置为非常大的值,那样程序可能会运行很久)。 运行结果如下 ⬇️

2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97