一般的なシステム開発では乱数を扱うことはそこまで多くないかもしれません。
しかし、ゲームや抽選を行うシステム、セキュリティ関連の機能実装などでは乱数を用いてランダムな挙動を実現しなければいけないことがあります。
そこで、今回はJavaで乱数を実装したい場合にどんな方法があるのかをお話しします。
①java.util.Randomクラスを使った乱数の実装
一つ目の方法は、java.util.Randomクラスを使った乱数の実装です。
以下のimport文を書いて、処理の本文で乱数生成メソッドを利用します。
import java.util.Random;
そして、処理内で以下のように記述すると、0から127までの乱数を生成してコンソールに表示することが出来ます。
int rndNum = 0;
//Randomクラスを生成
Random rnd = new Random();
//0から127までの乱数を生成(1から128までの乱数でないことに注意)
rndNum = rnd.nextInt(128);
//乱数の値を出力
System.out.println("乱数の値は" + rndNum);
実際に動作をすると以下のようになりました。

上記の処理を何度か実行してみると実行するたびに値が変わることが確認出来、乱数が生成されていることが確認できます。
②Math.Random()を使った乱数の生成
乱数を生成するメソッドはMath.Random()というメソッドも用意されています。
こちらは何もimportする必要がないのですが、値をdouble型で返します。
そして、返す値の範囲は0以上1未満で、小数の形式で値が返されます。
実際にコードを書いてみると以下のようになります。
double rndDbl = 0.0;
//Math.Random()による乱数生成(0以上1未満)
rndDbl = Math.random();
//乱数の値を出力
System.out.println("乱数の値は" + rndDbl);
この処理を実行してみると、以下のような表示となりました。

実行するたびに値が変わりますが、返ってきた値をそのまま使うとなると使用するケースが限られそうです。
実際にこの方法を乱数生成に使うとなると、返ってきた値を1000倍して整数部を取り出して、整数(例えば128など)で除算した余りを乱数として用いるなど、一工夫必要な乱数という印象です。
③java.util.concurrent.ThreadLocalRandomクラスを用いた乱数生成
乱数を生成する手段として、java.util.concurrent.ThreadLocalRandomクラスをimportして乱数生成を行うという手段があります。
この方法はJava7以降でしか利用できませんが、クラスをnewで生成しなくても乱数生成のメソッドが実装可能です。
まず、以下のように、java.util.concurrent.ThreadLocalRandomクラスをimportします。
import java.util.concurrent.ThreadLocalRandom;
そして、次のように処理を書いてみます。
int rndThreadNum = 0;
//1から128までの乱数を生成する
rndThreadNum = ThreadLocalRandom.current().nextInt(1,129);
//乱数の値を出力する
System.out.println("乱数の値は" + rndThreadNum);
実際に実行すると以下のような乱数を生成します。

この実装方法でも、実行するたびに異なる乱数を生成している様子が確認できます。
この方法は並列処理で乱数を生成するのに向いており、乱数を生成する速度も速いという特徴があります。
④SecureRandomクラスを使う場合
乱数を生成する手段として、SecureRandomクラスを使うという方法もあります。
クラス名にSecureと名がつく通り、セキュリティ面で強固な乱数を生成するのが特徴で、セキュリティを意識した乱数を生成したい場合はこちらを使うと良いでしょう。
実装方法ですが、まず、java.security.SecureRandomクラスをインポートします。
import java.security.SecureRandom;
そして、処理内でクラスを生成し、乱数を生成するメソッドを実行します。
例えば、以下のようにコードの記述を行います。
int secRndNum = 0;
//SecureRandomのクラスを生成
SecureRandom secRnd = new SecureRandom();
//1から128までの乱数を生成
secRndNum = secRnd.nextInt(1, 129);
//乱数の値を出力する
System.out.println("乱数の値は" + secRndNum);
実際に実行すると以下のような乱数を生成しました。

この方法も、実行するたびに異なる乱数を生成する様子が確認できます。
まとめ
今回はJavaでランラムな数字を生成する処理(乱数を生成する処理)として以下の4つを紹介しました。
- java.util.Randomクラスを使う方法
- Math.Random()を使う方法
- java.util.concurrent.ThreadLocalRandomクラスを使う方法
- SecureRandomクラスを使う方法
セキュリティ面で特にこだわりがなければ①~③の方法で、実装するのが良いでしょう。
マルチスレッドで並列処理を行いながら乱数生成が必要な場合は③、セキュリティに強固な乱数を生成したい場合は④と使い分けることが出来れば、問題なく乱数処理を実装出来ます。
それ以外の場合は②のMath.Random()は0以上1未満のdouble型の値を返すため、後処理が必要となることから、①のjava.util.Randomクラスを使う方法がスッキリとしたコードを書くことが出来るのではないでしょうか。
この記事を書いている自分は乱数を生成するコードの保守や実装に携わったことがありませんが、乱数はいろいろな用途で用いられます。
今回紹介した4つの方法の特徴をよく覚えて、状況に合わせた乱数生成の実装が出来るようになれば、エンジニアの引き出しから取り出せる道具が一つ増えますので、乱数を生成する方法もSEやPGとして食べていく場合は頭の片隅に入れておくとよいでしょう。
今回の記事はここまでとなります。
また次の記事でお会いしましょう。