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;
}

上記のソリューションは、20までの数値に対して問題なく機能します。 ただし、20より大きいものを試してみると、の結果が大きすぎてlong に収まらず、オーバーフローが発生するため、失敗します。

これらのそれぞれが少数でのみ機能することに注意して、もう少し見てみましょう。

2.2. Java8ストリームを使用した階乗

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()を使用しました。これは、削減ステップにID値とアキュムレータ関数を使用します。

2.3. 再帰を使用した階乗

そして、今度は再帰を使用した階乗プログラムの別の例を見てみましょう。

public long factorialUsingRecursion(int n) {
    if (n <= 2) {
        return n;
    }
    return n * factorialUsingRecursion(n - 1);
}

2.4. ApacheCommonsMathを使用した階乗

Apache Commons Math には、階乗の計算に使用できる静的なfactorialメソッドを持つCombinatoricsUtilsクラスがあります。

Apache Commons Mathを含めるには、commons-math3依存関係pomに追加します。

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

CombinatoricsUtilsクラスを使用した例を見てみましょう。

public long factorialUsingApacheCommons(int n) {
    return CombinatoricsUtils.factorial(n);
}

自社開発のソリューションと同様に、リターンタイプがlongであることに注意してください。

つまり、計算値が Long.MAX_VALUE を超えると、MathArithmeticExceptionがスローされます。

さらに大きくするには、別のリターンタイプが必要になります。

3. 20を超える数の階乗

3.1. BigIntegerを使用した階乗

前に説明したように、 長いですデータ型は階乗にのみ使用できます n <= 20

n の値が大きい場合、java.mathパッケージのBigIntegerクラスを使用できます。これは最大2^Integerの値を保持できます。 MAX_VALUE

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. グアバを使用した階乗

GoogleのGuavaライブラリは、より大きな数の階乗を計算するためのユーティリティメソッドも提供します。

ライブラリを含めるために、そのguava依存関係pomに追加できます。

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

これで、BigIntegerMathクラスの静的factorialメソッドを使用して、指定された数値の階乗を計算できます。

public BigInteger factorialUsingGuava(int n) {
    return BigIntegerMath.factorial(n);
}

4. 結論

この記事では、コアJavaといくつかの外部ライブラリを使用して階乗を計算するいくつかの方法を見ました。

20までの数値の階乗を計算するためにlongデータ型を使用するソリューションを最初に見ました。 次に、BigIntegerを20より大きい数値に使用するいくつかの方法を見ました。

この記事で紹介するコードは、Githubから入手できます。