はじめに
Javaで特定の範囲(たとえば min 以上 max 未満)で int 型の疑似乱数を生成したい場合、次のような方法が紹介されることがあります。
/**
* min(これを含む)から max(これを含まない)までの範囲で疑似乱数の int 値を返します。
* @param min 返される最小の値(これを含む)
* @param max 返される最大の値(これを含まない)
* @return min(これを含む)から max(これを含まない)までの範囲で疑似乱数の int 値
* @throws IllegalArgumentException max が min 以下の場合
*/
public int randomInt(int min, int max) {
if (min >= max) {
throw new IllegalArgumentException("max must be greater than min");
}
return min + (int)(Math.random() * (max - min));
}
この実装でも乱数の生成は可能ですが、Math.random() は double 型を返すため、int へのキャストが必要になり、やや冗長で直感的ではありません。
推奨:ThreadLocalRandom を使う
Java 7以降では、Random クラスとその派生クラスである ThreadLocalRandom や SecureRandom が提供する nextInt(int origin, int bound) メソッドを利用するのが一般的で、推奨されます。
import java.util.concurrent.ThreadLocalRandom;
public int randomInt(int min, int max) {
if (min >= max) {
throw new IllegalArgumentException("max must be greater than min");
}
return ThreadLocalRandom.current().nextInt(min, max);
}
補足:Java 7 は 2011 年にリリースされており、現在では企業・個人を問わず広く利用されているバージョンです。Java 7 以降の機能は、現代的な開発環境のスタンダードと見なされており、特別な理由がない限り、これらの機能を活用することが推奨されます。
ThreadLocalRandom をおすすめする理由
可読性と明快さ
nextInt(min, max) という形式のメソッドは、どの範囲の値を生成するのかがコードから明確に読み取れるため、保守性や理解のしやすさが向上します。
スレッドセーフかつ高速
ThreadLocalRandom は各スレッドごとに乱数生成器を持つ設計になっており、Random のようにロックを使用しないため、マルチスレッド環境でも非常に高速です。並列処理の多いアプリケーションでは特に有効です。
多くのユースケースに対応
ThreadLocalRandom は、ゲームロジック、Webアプリケーション、非暗号目的の一時ID生成、シャッフル処理、ランダムサンプリングなど、幅広い用途で安全かつ効率的に使用できます。セキュリティが要求されない限り、大半のユースケースでこのクラスを使えば十分です。
例外的に SecureRandom を使うべきケース
パスワードやトークン、暗号キーなどセキュリティが要求される用途では、より高品質な乱数を生成する SecureRandom を使う必要があります。こちらは暗号論的に安全な乱数生成器です。
補足リンク
実行環境
- javac 21.0.6
- openjdk 21.0.6 2025-01-21 LTS