1. 基础理论

先简单过下基础概念:
质数:只能被1和自身整除的自然数(大于1)
合数:非质数的自然数
⚠️ 特殊情况:数字1既不是质数也不是合数

本文将探讨在Java中判断质数的三种主流方案,各有适用场景。

2. 自定义实现方案

核心思路:检查2到该数平方根范围内是否存在能整除的数。
关键优化:只需检查到平方根即可,因为更大的因数必然对应更小的因数。

boolean isPrime(int number) {
    return number > 1 
      && IntStream.rangeClosed(2, (int) Math.sqrt(number))
      .noneMatch(n -> (number % n == 0));
}

💡 踩坑提示:注意边界条件(number<=1时直接返回false)

3. 使用BigInteger类

当处理超大整数(超过64位)时,BigInteger的isProbablePrime()是更优选择:

3.1 原理说明

  • 返回false时100%是合数
  • 返回true时是概率性质数(通过Miller-Rabin和Lucas-Lehmer算法)
  • 位数<100时仅用Miller-Rabin测试
  • 确定性(certainty)参数控制检验强度
boolean isPrimeByBigInteger(int number) {
    BigInteger bigInt = BigInteger.valueOf(number);
    return bigInt.isProbablePrime(100); // 确定性参数100
}

⚠️ 注意:此方法适合大数场景,小数场景可能存在性能浪费

4. 使用Apache Commons Math

引入依赖后可直接调用现成API:

4.1 Maven依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-math3</artifactId>
    <version>3.6.1</version>
</dependency>

4.2 使用方法

Primes.isPrime(number); // 直接返回boolean结果

✅ 优势:代码简洁,经过充分测试
❌ 劣势:需要引入额外依赖

5. 批量查找数组中的质数

给定数组示例:

int[] theArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

5.1 使用Stream API实现

三种方案均可通过Stream管道优雅实现:

// 方案1:自定义实现
Set<Integer> result = Arrays.stream(theArray)
  .filter(PrimeChecker::isPrime)
  .boxed()
  .collect(Collectors.toSet());

// 方案2:BigInteger实现
Set<Integer> resultByBigIntegerApproach = Arrays.stream(theArray)
  .filter(PrimeChecker::isPrimeByBigInteger)
  .boxed()
  .collect(Collectors.toSet());

// 方案3:Apache Commons Math
Set<Integer> resultByApacheCommonsMath = Arrays.stream(theArray)
  .filter(Primes::isPrime)
  .boxed()
  .collect(Collectors.toSet());

5.2 关键技巧

✅ **boxed()**:将IntStream转为Stream<Integer>以便收集到Set
方法引用PrimeChecker::isPrime使代码更简洁
链式调用:Stream API使逻辑一目了然

6. 方案对比总结

方案 适用场景 优势 缺点
自定义实现 中小数字,无外部依赖 无需引入库,性能可控 大数场景效率低
BigInteger 超大数字(>64位) 概率性算法高效处理大数 小数场景性能浪费
Apache Commons Math 快速开发,依赖允许 代码简洁,可靠性高 需要额外引入依赖

💡 经验建议:

  • 常规数字用自定义实现
  • 大数场景用BigInteger
  • 项目已用Commons Math时直接调用其API

完整代码示例见:GitHub仓库


原始标题:Check If a Number Is Prime in Java