0
点赞
收藏
分享

微信扫一扫

Java随机数生成Random类​使用示例

Java随机数生成Random类

Random类

java.Util.Random类,此类的一个实例用于生成伪随机数流,如果使用相同的种子创建了两个Random实例,并且对每个实例进行了相同的方法调用序列,则它们将生成并返回相同的数字序列。

java.util.Random 的实例是线程安全的。但是,在多个线程中并发使用同一个java.util.Random实例可能会遇到争用问题,从而导致性能不佳。可以考虑在多线程设计中使用java.util.concurrent.ThreadLocalRandom类。

java.util.Random的实例在加密方面并不安全。可以考虑使用java.security.SecureRandom来获取加密安全的伪随机数生成器,以供安全敏感的应用程序使用。


构造方法

public Random()

创建一个新的随机数生成器。此构造函数将随机生成一个种子,它的值很可能与此构造函数的其他任何调用者使用的值都相同(确保种子的唯一性)

public Random(long seed)

使用单个长种子创建新的随机数生成器。种子是由next方法维护的伪随机数生成器内部状态的初始值。

调用 new Random(seed) 等同于:

Randomrnd = new Random();
rnd.setSeed(seed);

常提供的seed有:

System.currentTimeMillis(); //本机当前的毫秒值
System.nanoTime();    //本机当前的纳秒值

如果使用相同的种子创建了两个 Random 实例,并且对每个实例进行了相同的方法调用序列,则它们将生成并返回相同的数字序列。如下两个Random的对象r1和r2使用相同的seed,故它们生成的随机数是一样的,代码:

public class RandDemo {
 public static void main(String[] args) {
 // 系统当前毫秒值,也可用System.nanoTime()
 long seed = System.currentTimeMillis();
 // 创建Random对象r1
 Random r1 = new Random(seed);
 // 创建Random对象r2
 Random r2 = new Random(seed);
 // r1和r2生成10个相同的伪随机数
 for (int i = 0; i < 3; i++) {
 System.out.println("======第" + (i + 1) + "次======");
 System.out.println(r1.nextInt());
 System.out.println(r2.nextInt());
 }
 /* 笔者在运行这段代码时的输出:
 ======第1次======
 -1705500708
 -1705500708
 ======第2次======
 1375764432
 1375764432
 ======第3次======
 -2111979661
 -2111979661
 */
 }
}

所以,要知晓Random对象的伪随机特性,随机只是表明调用随机方法时生成的数是按相等概率分布的,并不代表不能被预测,否则就是真随机数了,而这在计算机里是做不到的。

常用方法

public int nextInt()

此方法返回此随机数生成器序列中的下一个伪随机均匀分布的int值。nextInt的一般约定是生成并返回一个int值。

返回值这个随机数生成器序列中的下一个伪随机均匀分布的int值,即int范围内的任一随机数。

public int nextInt(int bound)

返回一个伪随机、均匀分布的整数值,该值在0(包括)和指定值bound(不包括)之间,从该随机数生成器的序列中抽取。nextInt的通用约定是,在指定范围内,一个int值是伪随机生成并返回的。所有可能的 int 值都是以(近似)相等的概率产生的。

参数bound – 上限(不包括上限)。必须为正数。

范围值下一个伪随机、均匀分布的整数值,介于此随机数生成器序列的零(包括)和边界(不包括)之间

举例:

Random r = new Random();
// 生成一个0-100的整数值
int randNum1 = r.nextInt(101);
// 生成一个1-100之间的整数值
int randNum2 = r.nextInt(100) + 1;

System.out.println(randNum1);
System.out.println(randNum2);

此外还有nextLong()、nextBoolean()、nextFloat()、nextDouble()方法。


Math.random()方法

java.lang.Math.random()方法,其本质就是调用Random类的nextDouble()方法。

本方法返回一个带有正号的双精度值,大于或等于0.0(包含)并小于1.0(不包含)。返回的值是(近似)均匀分布在该范围内的伪随机值。

当首次调用此方法时,它会创建一个新的伪随机数生成器,如下:

new java.util.Random()

此后,此新的伪随机数生成器用于对此方法的所有调用,并且不用于其他任何地方。

此方法已正确同步,允许多个线程正确使用。但是,(由于底层就是使用Random类,所以其特性与Random一样)如果许多线程需要以极高的速率生成伪随机数,则每个线程拥有自己的伪随机数生成器可能会减少争用,此时应考虑使用java.util.concurrent.ThreadLocalRandom类。

应用

返回指定范围的随机数min(包含)到max(不包含)之间的公式:

Math.random() * (max-min) + min;

如下示例方法:

public class RandDemo2 {
 public static void main(String[] args) {
 for (int i = 0; i < 100; i++) {
 //System.out.println(getRandom());
 //System.out.println(getRandomArbitrary(0, 100));
 //System.out.println(getRandomInt(0, 100));
 //System.out.println(getRandomIntInclusive(1, 100));
 //System.out.println(getRandomLowercaseLetter());
 System.out.println(getRandomVisibleCharacter());

 }
 }

 /**
 * 得到一个大于等于0,小于1 之间的随机double类型的数
 * @return 返回[0,1)之间的一个随机double值
 */
 public static double getRandom() {
 return Math.random();
 }

 /**
 * 得到一个两数之间的随机数
 * 这个例子返回了一个在指定值之间的随机数。
 * 这个值在min(包含)与max(不包含)之间。
 * @param min 下区间(包含)
 * @param max 上区间(不包含)
 * @return 返回[min,max)区间内的double值
 */
 public static double getRandomArbitrary(int min, int max) {
 return (Math.random() * (max - min) + min);
 }

 /**
 * 这个例子返回了一个在指定值之间的随机整数。
 * 这个值不小于min (包含),且小于(不包含)max。
 * @param min 下区间(包含)
 * @param max 上区间(不包含)
 * @return 在[min,max)区间内的随机整数
 */
 public static int getRandomInt(int min, int max) {
 return (int) (Math.floor(Math.random() * (max - min)) + min); //不含最大值,含最小值
 }

 /**
 * 上一个例子提到的函数getRandomInt() 结果范围包含了最小值,但不含最大值。
 * 如果你的随机结果需要同时包含最小值和最大值,怎么办呢?
 * getRandomIntInclusive() 函数可以实现。
 * @param min 下区间(包含)
 * @param max 上区间(不包含)
 * @return 在[min,max]区间内的随机整数
 */
 public static int getRandomIntInclusive(int min, int max) {
 return (int) (Math.floor(Math.random() * (max - min + 1)) + min); //含最大值,含最小值
 }

 /**
 * 生成一个ASCII码表中随机小写字母,a-z之间
 * @return 生成一个随机字符a-z之间
 */
 public static char getRandomLowercaseLetter(){
 return (char) (Math.random() * ('z' - 'a' + 1) + 'a');
 }

 /**
 * 生成一个ASCII码表中的!到~之间的可见字符
 * @return 生成一个ASCII码表中的!到~之间的可见字符
 */
 public static char getRandomVisibleCharacter(){
 return (char) (Math.random() * ('~' - '!' + 1) + '!');
 }
}





举报

相关推荐

0 条评论