ゲームのサイコロ・テストデータの自動生成・シミュレーション計算——Javaで乱数を使う場面は多岐にわたります。しかし「Math.random()とRandomクラスのどちらを使えばよいか」「範囲を指定するにはどう書くか」で迷う方は少なくありません。
この記事では、Javaで乱数を生成する主要な方法を基本構文・コード例・使い分けの判断基準まで含めて解説します。初心者が最初につまずくポイントと、実務で使える応用例も合わせて紹介します。
Javaで乱数を使う目的

乱数の基本概念と用途
乱数とは、規則性のないランダムな数値のことです。プログラムの中で乱数を使うことで、実行するたびに異なる値を生成でき、動作に変化や不確実性を持たせられます。
Javaが生成する乱数は厳密には疑似乱数(Pseudo-random number)です。内部的なアルゴリズム(線形合同法など)に基づいて計算された数値で、真の意味でのランダムではありませんが、多くのアプリケーションで十分に活用できます。
ゲーム開発やテストデータ作成での活用例
- ゲーム開発: サイコロ・カードのシャッフル・敵の行動パターン・ドロップアイテムの確率決定
- テストデータ: ランダムなユーザーID・商品価格・数値データの自動生成
- UI/UX: バナー画像のランダム表示・アンケートの選択肢順序のシャッフル
- 数値計算: モンテカルロ法などの確率的シミュレーション
条件分岐やシミュレーションで必要な場面
乱数は「一定の確率でAまたはBの処理を実行する」という条件分岐にも使われます。たとえばゲームのキャラクターが30%の確率でクリティカルヒットを出す処理や、天気シミュレーションで降雨確率を再現する処理がこれにあたります。
Javaで乱数を生成する方法の種類

Math.random()を使った生成方法
基本構文と返り値の型
Math.random()はjava.lang.Mathクラスの静的メソッドです。インポートなし・インスタンス生成なしで即座に使えるため、シンプルな乱数生成に向いています。
// 基本構文
double randomValue = Math.random();
System.out.println(randomValue);
返り値はdouble型で、常に0.0以上1.0未満の値を返します。
0以上1未満の乱数の取得方法
public class MathRandomBasic {
public static void main(String[] args) {
double value = Math.random();
System.out.println("生成された乱数: " + value);
// 実行例: 生成された乱数: 0.7342918462...
}
}
任意の範囲に変換する方法
Math.random()の返り値に乗算とキャストを組み合わせることで、任意の整数範囲に変換できます。
// 0以上9以下の整数(0〜9)
int value = (int)(Math.random() * 10);
// 1以上10以下の整数(1〜10)
int value = (int)(Math.random() * 10) + 1;
// min以上max以下の整数
int min = 5;
int max = 15;
int value = (int)(Math.random() * (max - min + 1)) + min;
計算の考え方: Math.random() * (max - min + 1)で範囲の幅だけランダム値を広げ、+ minで開始位置をずらします。(int)キャストで小数点以下を切り捨てて整数にします。
Randomクラスを使った生成方法
Randomオブジェクトの生成方法
Randomクラスはjava.utilパッケージに含まれます。使用前にインポートとインスタンス生成が必要ですが、より柔軟な乱数生成が可能です。
import java.util.Random;
Random random = new Random(); // シード値なし(実行ごとに異なる乱数)
Random random = new Random(42); // シード値あり(再現性のある乱数)
nextInt()、nextDouble()などメソッドの使い方
| メソッド | 返り値の型 | 生成される範囲 |
|---|---|---|
nextInt() |
int | int型の全範囲 |
nextInt(n) |
int | 0以上n未満 |
nextDouble() |
double | 0.0以上1.0未満 |
nextFloat() |
float | 0.0以上1.0未満 |
nextLong() |
long | long型の全範囲 |
nextBoolean() |
boolean | trueまたはfalse |
import java.util.Random;
public class RandomMethods {
public static void main(String[] args) {
Random random = new Random();
int intVal = random.nextInt(); // int全範囲の乱数
int intRange = random.nextInt(10); // 0〜9の整数
double dblVal = random.nextDouble(); // 0.0〜1.0未満の小数
boolean boolVal = random.nextBoolean(); // trueまたはfalse
System.out.println("int乱数: " + intVal);
System.out.println("0〜9の整数: " + intRange);
System.out.println("小数乱数: " + dblVal);
System.out.println("boolean乱数: " + boolVal);
}
}
範囲指定の乱数取得方法
nextInt(n)は0以上n未満の整数を返します。min〜maxの範囲に変換するには以下の計算式を使います。
// min以上max以下の整数乱数
int min = 10;
int max = 20;
int result = random.nextInt(max - min + 1) + min;
System.out.println(result); // 10〜20のいずれかの整数
シード値を使った再現性のある乱数生成
シード値とは乱数生成の初期値です。同じシード値を指定すると、毎回同じ順序で乱数が生成されます。テストやデバッグで「同じ乱数列を再現したい」場合に使います。
import java.util.Random;
public class SeedExample {
public static void main(String[] args) {
Random random1 = new Random(100); // シード値100
Random random2 = new Random(100); // 同じシード値100
// 2つのRandomは同じ乱数列を生成する
System.out.println(random1.nextInt(50)); // 例: 23
System.out.println(random2.nextInt(50)); // 例: 23(同じ)
}
}
注意: シード値が同じだと乱数列が予測可能になります。本番環境やセキュリティが必要な場面でシード値を固定することは避けてください。
整数の乱数を生成する方法

0以上指定値未満の整数乱数
最もシンプルなパターンです。nextInt(n)に上限値を渡します。
import java.util.Random;
public class IntRandom {
public static void main(String[] args) {
Random random = new Random();
// 0以上10未満(0〜9)
int value = random.nextInt(10);
System.out.println("0〜9の乱数: " + value);
// Math.random()を使う場合
int value2 = (int)(Math.random() * 10);
System.out.println("0〜9の乱数(Math): " + value2);
}
}
指定範囲内の整数乱数(min〜max)
1〜6のサイコロのように、下限値と上限値を両方指定したい場合の書き方です。Javaの乱数生成の詳しい解説と実践コード例はこちらの記事も参考になります。
import java.util.Random;
public class RangeRandom {
public static void main(String[] args) {
Random random = new Random();
int min = 1;
int max = 6;
// Randomクラスを使う方法
int dice = random.nextInt(max - min + 1) + min;
System.out.println("サイコロの目: " + dice); // 1〜6
// Math.random()を使う方法
int dice2 = (int)(Math.random() * (max - min + 1)) + min;
System.out.println("サイコロの目(Math): " + dice2); // 1〜6
}
}
計算式のポイントをまとめます。
| 目的 | Randomクラス | Math.random() |
|---|---|---|
| 0〜n-1の整数 | random.nextInt(n) |
(int)(Math.random() * n) |
| min〜maxの整数 | random.nextInt(max-min+1)+min |
(int)(Math.random()*(max-min+1))+min |
ループや配列と組み合わせた乱数の活用例
複数の乱数を生成してint配列に格納する例です。
import java.util.Random;
public class ArrayRandom {
public static void main(String[] args) {
Random random = new Random();
int[] scores = new int[5];
// 0〜100の乱数を5つ生成して配列に格納
for (int i = 0; i < scores.length; i++) {
scores[i] = random.nextInt(101); // 0〜100
}
// 配列の内容を表示
System.out.print("スコア一覧: ");
for (int score : scores) {
System.out.print(score + " ");
}
// 実行例: スコア一覧: 87 42 95 13 76
}
}
小数(実数)の乱数を生成する方法
0以上1未満の小数乱数
確率判定やシミュレーションで最もよく使われるパターンです。
import java.util.Random;
public class DoubleRandom {
public static void main(String[] args) {
// Randomクラス
Random random = new Random();
double value1 = random.nextDouble();
System.out.println("小数乱数(Random): " + value1);
// 実行例: 0.5821039274...
// Math.random()
double value2 = Math.random();
System.out.println("小数乱数(Math): " + value2);
// 実行例: 0.3149872631...
}
}
任意範囲の小数乱数(min〜max)
0.0〜1.0の値に範囲の幅を掛け、開始値を加算することで任意の範囲に変換できます。
import java.util.Random;
public class DoubleRangeRandom {
public static void main(String[] args) {
Random random = new Random();
double min = 1.5;
double max = 3.5;
// min以上max未満の小数乱数
double value = random.nextDouble() * (max - min) + min;
System.out.println("1.5〜3.5の乱数: " + value);
// 実行例: 2.7341...
// Math.random()を使う場合
double value2 = Math.random() * (max - min) + min;
System.out.println("1.5〜3.5の乱数(Math): " + value2);
}
}
シミュレーションや計算に使う例
モンテカルロ法で円周率(π)を近似計算する例です。乱数を使ったシミュレーションの代表的な活用例です。
import java.util.Random;
public class MonteCarlo {
public static void main(String[] args) {
Random random = new Random();
int total = 1000000; // 試行回数
int inside = 0;
for (int i = 0; i < total; i++) {
double x = random.nextDouble(); // 0.0〜1.0
double y = random.nextDouble(); // 0.0〜1.0
// 単位円の内側かどうかを判定
if (x * x + y * y <= 1.0) {
inside++;
}
}
double pi = 4.0 * inside / total;
System.out.println("πの近似値: " + pi);
// 実行例: πの近似値: 3.14159...
}
}
乱数生成の注意点
同じ乱数が出ることがある(シード値の影響)
JavaのRandomクラスはシード値を指定しない場合、現在時刻をもとに自動でシード値を設定します。しかし非常に短い時間内に複数のRandomインスタンスを生成すると、同じシード値が割り当てられ同じ乱数列が生成されることがあります。
対策: アプリケーション内ではRandomインスタンスを1つだけ生成して使い回す設計にしましょう。
// 悪い例:ループ内で毎回インスタンスを生成する
for (int i = 0; i < 10; i++) {
Random random = new Random(); // 同じシード値になる可能性がある
System.out.println(random.nextInt(100));
}
// よい例:インスタンスを1つ使い回す
Random random = new Random();
for (int i = 0; i < 10; i++) {
System.out.println(random.nextInt(100));
}
予測可能な乱数とセキュリティ用途の違い
Math.random()とRandomクラスが生成する乱数は疑似乱数であり、アルゴリズムが既知のため理論上は予測可能です。パスワード生成・トークン・暗号鍵などセキュリティが重要な用途には使用しないでください。
セキュリティが必要な場面ではjava.security.SecureRandomクラスを使います。
import java.security.SecureRandom;
public class SecureRandomExample {
public static void main(String[] args) {
SecureRandom secureRandom = new SecureRandom();
int token = secureRandom.nextInt(1000000); // セキュアな乱数
System.out.println("セキュアトークン: " + token);
}
}
| 用途 | 推奨クラス | 理由 |
|---|---|---|
| ゲーム・シミュレーション | Random / Math.random() | 速度が速く十分な乱雑性 |
| テストデータ生成 | Random | シード値で再現可能 |
| パスワード・トークン生成 | SecureRandom | 暗号学的に安全な乱数 |
大規模データでの性能面の注意
乱数生成自体は軽量な処理ですが、数百万回のループで乱数を生成する場合は性能に影響が出ることがあります。Java 8以降ではSplittableRandomクラスがスレッドセーフかつ高速な乱数生成を提供しています。Java乱数の性能比較と使い分けの詳細はこちらの解説も参考になります。
import java.util.SplittableRandom;
// Java 8以降:高速な乱数生成
SplittableRandom sr = new SplittableRandom();
int value = sr.nextInt(1, 101); // 1〜100の整数(Java 8以降の範囲指定構文)
応用例
サイコロやカードのランダム生成
1〜6のサイコロと、トランプの52枚からカードを1枚引く例です。JavaのMath.random()を使ったゲーム処理の具体例はこちらの記事も参考になります。
import java.util.Random;
public class GameRandom {
public static void main(String[] args) {
Random random = new Random();
// サイコロ(1〜6)
int dice = random.nextInt(6) + 1;
System.out.println("サイコロ: " + dice);
// トランプのスート(0〜3)とランク(1〜13)
String[] suits = {"スペード", "ハート", "ダイヤ", "クラブ"};
int suit = random.nextInt(4);
int rank = random.nextInt(13) + 1;
System.out.println("カード: " + suits[suit] + " " + rank);
// 実行例: カード: ハート 7
}
}
配列やリストのシャッフル
配列をランダムにシャッフルする方法です。Collections.shuffle()を使う方法と、手動でシャッフルする方法を示します。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class ShuffleExample {
public static void main(String[] args) {
// Collections.shuffle()を使う方法(推奨)
List<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
numbers.add(i);
}
Collections.shuffle(numbers);
System.out.println("シャッフル後: " + numbers);
// 実行例: [5, 2, 9, 1, 7, 3, 10, 4, 6, 8]
// int配列を手動シャッフル(Fisher-Yatesアルゴリズム)
Random random = new Random();
int[] arr = {1, 2, 3, 4, 5};
for (int i = arr.length - 1; i > 0; i--) {
int j = random.nextInt(i + 1);
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
System.out.print("手動シャッフル: ");
for (int v : arr) System.out.print(v + " ");
}
}
乱数を使った条件分岐やゲームの動作
確率による条件分岐の実装例です。RPGゲームのクリティカルヒット判定を模した処理です。Javaの乱数を使ったゲームロジックの応用例はこちらも参考になります。また、Javaを含むプログラミング全般の実践ガイドはkakiro-webでも発信しています。
import java.util.Random;
public class CriticalHit {
public static void main(String[] args) {
Random random = new Random();
int baseDamage = 50;
// 乱数を使った確率分岐
double chance = random.nextDouble(); // 0.0〜1.0未満
int finalDamage;
String result;
if (chance < 0.10) {
// 10%の確率でクリティカルヒット(ダメージ2倍)
finalDamage = baseDamage * 2;
result = "クリティカルヒット!";
} else if (chance < 0.30) {
// 20%の確率でミス(ダメージなし)
finalDamage = 0;
result = "ミス!";
} else {
// 70%の確率で通常ヒット
finalDamage = baseDamage;
result = "ヒット";
}
System.out.println(result + " ダメージ: " + finalDamage);
}
}
まとめ
Math.random()とRandomクラスの使い分け方
| 比較項目 | Math.random() | Randomクラス |
|---|---|---|
| インポート | 不要 | java.util.Randomが必要 |
| インスタンス生成 | 不要 | 必要(new Random()) |
| 返り値の型 | doubleのみ | int・double・boolean等 |
| 範囲指定 | 計算式が必要 | nextInt(n)で直接指定可能 |
| シード値指定 | 不可 | 可能 |
| おすすめ場面 | シンプルな1回の乱数生成 | 整数・複数・再現性が必要な場合 |
整数・小数の乱数生成方法を理解する
- 整数乱数:
random.nextInt(max - min + 1) + minでmin〜maxの範囲を指定 - 小数乱数:
random.nextDouble() * (max - min) + minで任意範囲に変換 - シード値を固定すると同じ乱数列が再現できる(テスト・デバッグ向け)
- セキュリティ用途には
SecureRandomを使う Randomインスタンスはループ外で1つだけ生成して使い回す
用途に応じて乱数を活用することでプログラムの柔軟性を高められる
シンプルな乱数が必要ならMath.random()、整数範囲の指定や再現性が必要ならRandomクラス、セキュリティが求められるならSecureRandomと使い分けることが、Javaでの乱数活用の基本方針です。まずはRandomクラスのnextInt()を使いこなすことを目標に、実際のコードで試してみてください。

