Javaで乱数を使う機会は多い。
例えばパスワードをランダムで発行したいとき、例えばスロットやおみくじなどのランダム要素をプログラムに追加したいとき、乱数を使う必要がある。
このページではJavaで乱数を使う方法についてまとめている。初心者の方でもすぐに使えるように、簡単にまとめた。参考にして頂ければと思う。
目次
そもそも乱数とは?
乱数とは?
乱数とは次にどのような値が出るのかわからない数字のことだ。サイコロを思い出してもらえればわかりやすい。サイコロには1~6までの値があるが、振ってみないとどの目が出るのかわからない。これが乱数だ。
Javaで扱う乱数は整数だけではない。double型など小数点のある数値や、boolean型なども乱数として扱うことができる。
乱数はパスワードの暗号化などセキュリティに関する処理で使用されることが多い。また、カードゲームやアクションゲームなどのゲームアプリ全般でも、ゲーミング要素を高めるために乱数の使用は必須だ。乱数の生成処理は幅広く使われているので、基本をしっかり押さえておこう。
詳細はいいからとにかく乱数を出したい!という方
下記のようにMathクラスを使って出力を試してみよう。
Math.random();
上記を実行すると、0.0~1.0未満の範囲でdouble型の乱数を取得できる。
例えば、10種類の数字が出る乱数を作りたいとき、次のような手順を取ればいい。
- 上のメソッドで乱数を出す
- 10倍する(5種類だったら5倍、100種類だったら100倍)
- 整数型にする(intにキャストする)
以上だ。
1未満の数字がランダムで出るので、例えば10倍したら「0〜9」の数字が出るようになる。同じ理屈で、5個のランダム数字を作りたければ5倍にすればいいし、サイコロを作りたければ6倍すればいい。
それでは、詳細をご紹介していく。
乱数に関するクラスの種類
Javaプログラミングにおいて、乱数を生成する時に使用する代表的なクラスは以下の通りだ。
クラス |
内容 |
java.util.Random |
乱数を生成する |
java.lang.Math |
基本的な数値処理を実行する |
Randomクラス(java.util.Random)
Randomクラスはさまざまな型で乱数を作ることができるクラスだ。Randomクラスでの乱数生成はシード(種)と呼ばれる値をもとに、乱数ジェネレータから生成されている。
主なコンストラクタ
Random()
内容 |
新しい乱数ジェネレータを作成する。このコンストラクタではシードが省略されているので、シードとして現在時刻が使用される。 |
Random(long seed)
内容 |
long型のシードを指定して、新しい乱数ジェネレータを作成する。 |
主なメソッド
nextInt()
戻り値の型 |
int |
内容 |
int型が取り得る範囲でのint型乱数を取得する。 |
nextInt(int value)
戻り値の型 |
int |
内容 |
0~value-1までの範囲内のint型の乱数を取得する。 乱数の生成する範囲の指定もできる。 詳細は後で紹介するサンプルプログラムを見て欲しい。 |
nextLong()
戻り値の型 |
long |
内容 |
long型が取り得る範囲でのlong型の乱数を取得する。 |
nextDouble()
戻り値の型 |
double |
内容 |
0.0~1.0の範囲でdouble型の乱数を取得する。 |
nextFloat()
戻り値の型 |
float |
内容 |
0.0~1.0の範囲でfloat型の乱数を取得する。 |
nextBoolean()
戻り値の型 |
boolean |
内容 |
真(true)または偽(false)型の乱数を取得する。 |
サンプルプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import java.util.Random; public class Main { public static void main(String args[]) { //Randomクラスの生成(シード指定なし) Random rnd = new Random(); //[1] //乱数を取得する int iValue = rnd.nextInt(); //[2] int iValue2 = rnd.nextInt(); //[3] int iValue3 = rnd.nextInt(100); //[4] int iValue4 = rnd.nextInt(100) + 100; //[5] long lValue = rnd.nextLong(); //[6] double dValue = rnd.nextDouble(); //[7] float fValue = rnd.nextFloat(); //[8] boolean bValue = rnd.nextBoolean(); //[9] //取得した値を出力 System.out.println("[2]int型: " + iValue); System.out.println("[3]int型(2回目): " + iValue2); System.out.println("[4]int型(0-99): " + iValue3); System.out.println("[5]int型(100-199): " + iValue4); System.out.println("[6]long型: " + lValue); System.out.println("[7]double型: " + dValue); System.out.println("[8]float型: " + fValue); System.out.println("[9]boolean型: " + bValue); long seed = 1000; //シードを指定 //Randomクラスの生成(シード指定あり) Random rndSeed = new Random(seed); //[10] int iValueSd = rndSeed.nextInt(); //[11] int iValueSd2 = rndSeed.nextInt(); //[12] //シードを指定して取得した値を出力 System.out.println("[11]シード指定int型: " + iValueSd); System.out.println("[12]シード指定]int型(2回目): " + iValueSd2); //同じシードで別のRandomクラスを生成 Random rndSeed2 = new Random(seed); //[13] int iValueSd3 = rndSeed2.nextInt(); //[14] int iValueSd4 = rndSeed2.nextInt(); //[15] //取得した値を出力 System.out.println("[14]同一シード指定int型: " + iValueSd3); System.out.println("[15]同一シード指定int型(2回目): " + iValueSd4); } } |
実行結果
1 2 3 4 5 6 7 8 9 10 11 12 |
[2]int型: 366446358 [3]int型(2回目): -2132366311 [4]int型(0-99): 5 [5]int型(100-199): 134 [6]long型: -657212308939444689 [7]double型: 0.09989111650794158 [8]float型: 0.78745455 [9]boolean型: false [11]シード指定int型: -1244746321 [12]シード指定]int型(2回目): 1060493871 [14]同一シード指定int型: -1244746321 [15]同一シード指定int型(2回目): 1060493871 |
サンプルプログラムの説明
それでは簡単にサンプルプログラムを説明しよう。
- [1]Randomクラスのコンストラクタ。シードの指定はなし。
- [2]int型の乱数を生成している。
- [3]int型の乱数を生成している。[2]とは異なる値が生成されたが、乱数なので同じ値が生成されることもある。
- [4]0~99までの乱数を生成している。
- [5]100~199までの乱数を生成している。nextInd(value)+100なら、100~value - 1までの乱数。random.nextInd(value)+1000なら、1000~value - 1までの乱数になる。
- [6]long型の乱数を生成している。
- [7]double型の乱数を生成している。
- [8]float型の乱数を生成している。
- [9]boolean型の乱数を生成している。
- [10]Randomクラスのコンストラクタ。シードを指定して生成している。
- [11]int型の乱数を生成している。
- [12]int型の乱数を生成している。[11]とは異なる値が出力された。
- [13]Randomクラスのコンストラクタ。先ほどと同じシードを指定して生成している。
- [14]int型の乱数を生成しているが、同じシードを指定したRandomクラスなので[11]と同じ値が出力されている。
- [15]同じシードなので、2回目の乱数生成でも[12]と同じ値が出力されている。
シードの指定に注意
サンプルプログラムでも説明したが、シードを指定して乱数を生成する場合、同じシード値だと毎回同じ値が出力される。
サンプルプログラムではnextInt()メソッドでの出力のみ確認したが、他のいずれのメソッドでも同じ値が出力される。シードを指定する場合は注意が必要だ。
Mathクラス(java.lang.Math)
Mathクラスは指数関数や三角関数などの数値処理を行うクラスだ。このクラスにも乱数を生成するメソッドがあるので紹介しておこう。
主なメソッド
random()
戻り値の型 |
double |
内容 |
0.0~1.0未満の範囲でdouble型の乱数を取得する。 |
サンプルプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class Main { public static void main(String args[]) { //乱数生成 double dValue = Math.random(); double dValue2 = Math.random(); //乱数生成(int型で取得) double iValue = (int)(Math.random() * 10); double iValue2 = (int)(Math.random() * 10); //取得した値を出力 System.out.println("[1]double型: " + dValue); System.out.println("[2]double型(2回目): " + dValue2); System.out.println("[3]int型: " + iValue); System.out.println("[4]int型(2回目): " + iValue2); } } |
実行結果
1 2 3 4 |
[1]double型: 0.2560491463639476 [2]double型(2回目): 0.40933033202991675 [3]int型: 4.0 [4]int型(2回目): 3.0 |
サンプルプログラムの説明
こちらのサンプルプログラムも簡単に説明しよう。
- [1]double型の乱数を生成している。
- [2]double型の乱数を生成している。[1]とは異なる値が出力されている。
- [3]生成した乱数をint型で取得している。生成した乱数に10を掛けることで、0~9までの乱数が生成できる。
- random()メソッドの戻り値はdouble型なので、int型にキャストする必要がある。
- [4]こちらもint型で取得している。
まとめ
Javaでの乱数の使い方についてまとめてきたがいかがだっただろうか?
様々なメソッドがあるので、場合によって使い分けて乱数に対応していただければと思う。
math.random import.java.util.scanner を使ってnumberを生成できますか。
迷てしまいました。
いつもご愛読いただきありがとうございます。
math.random と import.java.util.scanner ということですので、キーボードからの入力と乱数を組み合わせる、例えばシード値をキーボードから入力した上でそれを元に乱数を生成する、というような処理でしょうか?
もしくは、キーボードから何か入力をするたびに自動的に乱数が生成されて画面に表示される、というような処理でしょうか?
お手数ですがご教示ください。よろしくお願いいたします。
nexBoolean()ではなくnextBoolean()では?
ご指摘いただきありがとうございます。
該当箇所の脱字修正いたしました。
引き続き、ご愛読のほど、よろしくお願いいたします。