1. 概述
给定一个非负整数 n,其阶乘是所有小于等于 n 的正整数的乘积。
在本教程中,我们将介绍 Java 中计算给定数字阶乘的不同方法。
2. 小于等于 20 的阶乘计算
2.1. 使用 for 循环实现
先来看一个基础的阶乘算法,使用 for 循环实现:
public long factorialUsingForLoop(int n) {
long fact = 1;
for (int i = 2; i <= n; i++) {
fact = fact * i;
}
return fact;
}
✅ 上述方法对 n <= 20* 的情况完全适用。但如果 *n > 20,就会出现 long 类型溢出,导致结果错误。
⚠️ 所以,下面介绍的这些方法也都 仅适用于较小的数字。
2.2. 使用 Java 8 Stream 实现
我们也可以使用 Java 8 的 Stream API 来计算阶乘,代码非常简洁:
public long factorialUsingStreams(int n) {
return LongStream.rangeClosed(1, n)
.reduce(1, (long x, long y) -> x * y);
}
这段代码中,我们首先使用 LongStream 遍历 1 到 n 之间的所有整数,然后通过 reduce() 方法进行累积计算。
2.3. 使用递归实现
再来看一个递归版本的实现:
public long factorialUsingRecursion(int n) {
if (n <= 2) {
return n;
}
return n * factorialUsingRecursion(n - 1);
}
⚠️ 递归虽然写法简洁,但要注意栈溢出问题,尤其是 n 较大时。
2.4. 使用 Apache Commons Math 实现
Apache Commons Math 提供了 CombinatoricsUtils 工具类,其中包含一个静态的 factorial 方法。
首先添加依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
使用方式如下:
public long factorialUsingApacheCommons(int n) {
return CombinatoricsUtils.factorial(n);
}
⚠️ 该方法返回类型仍然是 long,因此同样 无法处理 n > 20 的情况。超出范围时会抛出 MathArithmeticException。
3. 大于 20 的阶乘计算
3.1. 使用 BigInteger 实现
如前所述,long 类型只能处理 n <= 20 的阶乘。对于更大的值,我们可以使用 java.math.BigInteger 类,它能表示非常大的整数:
public BigInteger factorialHavingLargeResult(int n) {
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= n; i++)
result = result.multiply(BigInteger.valueOf(i));
return result;
}
✅ 这是处理大数阶乘的标准做法,没有溢出问题。
3.2. 使用 Guava 实现
Google 的 Guava 库也提供了计算大数阶乘的方法。
添加依赖:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
使用 BigIntegerMath 类的静态方法:
public BigInteger factorialUsingGuava(int n) {
return BigIntegerMath.factorial(n);
}
✅ Guava 的实现内部也是基于 BigInteger,使用起来更方便,代码更简洁。
4. 总结
本文介绍了多种在 Java 中计算阶乘的方式:
- 对于 n <= 20,可以使用 long 类型配合循环、递归或 Stream 实现;
- 对于更大数值,推荐使用 BigInteger 或借助 Guava、Apache Commons Math 等第三方库。
📌 本文所有代码示例均可在 GitHub 获取。