前言:这里将介绍两个能生成随机数的类 ThreadLocalRandom 类和 Random 类,与 Math 类所提供的随机方法 random( ) 相比,ThreadLocalRandom 类与 Random 类所提供的方法,都比 Math 类的 random( ) 方法提供了更多的方式,来生成各种伪随机数。它们可以生成浮点类型
的伪随机数,也可以生成整数类型
的伪随机数,还可以指定生成随机数的范围
。
文章目录
1、Random 类
1.1、Random 类的介绍
Rndom 类专门用于生成一个伪随机数,它有两个构造器:
import java.util.Arrays;
import java.util.Random;
public class RandomTest {
public static void main(String[] args) {
Random rand = new Random();
// 1、生成true或false
System.out.println("rand.nextBoolean():\t" + rand.nextBoolean());
// 2、生成随机字节并将它们放入用户提供的字节数组中。 bytes[i++] = (byte)nextInt();
byte[] buffer = new byte[16];
rand.nextBytes(buffer);
System.out.println(Arrays.toString(buffer));
// 3、生成 0.0~1.0 之间的伪随机 double 数
System.out.println("rand.nextDouble():\t" + rand.nextDouble());
// 4、生成 0.0~1.0 之间的伪随机 float 数
System.out.println("rand.nextFloat():\t" + rand.nextFloat());
// 5、生成平均值是 0.0,标准差是 1.0 的伪高斯数
System.out.println("rand.nextGaussian():\t" + rand.nextGaussian());
// 6、生成一个处于 int 整数取值范围的伪随机整数
System.out.println("rand.nextInt():\t" + rand.nextInt());
/* 生成 min-max:[min,max] 之间的伪随机整数,则为 rand.nextInt(max-min+1)+min,推导:
[0, max] -> next.nextInt(max + 1);
[min, max+min] -> next.nextInt(max + 1) + min;
[min, max] -> next.nextInt(max + 1 - min) + min;*/
System.out.println("next.nextInt(max + 1 - min) + min:\t" + rand.nextInt(20 + 1 - 15) + 15);
}
}
(2)运行结果
rand.nextBoolean(): true
[-26, -98, -90, 107, 24, -61, 125, -84, -41, 94, -56, -17, 26, -125, -94, -109]
rand.nextDouble(): 0.8362498709465734
rand.nextFloat(): 0.70504546
rand.nextGaussian(): -1.108647283595758
rand.nextInt(): -1780316130
next.nextInt(max + 1 - min) + min: 415
1.3、Random 类的注意点
从上面程序中可以看出,Random 可以提供很多方法来生成伪随机数。Random 使用一个 48位
的种子,如果这个类的两个实例是用同一个种子创建,对它们以同样的顺序调用方法,则它们会产生相同的数字序列。测试如下所示:
(1)代码表示
import java.util.Random;
public class SeedTest {
public static void main(String[] args) {
//显示的设置种子数为50
Random r1 = new Random(50);
System.out.println("第一个种子为 50 的Random对象");
System.out.println("r1.nextBoolean():\t" + r1.nextBoolean());
System.out.println("r1.nextDouble():\t" + r1.nextDouble());
System.out.println("r1.nextGaussian():\t" + r1.nextGaussian());
System.out.println("----------------------------");
//显示的设置种子数为50
Random r2 = new Random(50);
System.out.println("第二个种子为 50 的Random对象");
System.out.println("r2.nextBoolean():\t" + r2.nextBoolean());
System.out.println("r2.nextDouble():\t" + r2.nextDouble());
System.out.println("r2.nextGaussian():\t" + r2.nextGaussian());
System.out.println("----------------------------");
//显示的设置中字数为100
Random r3 = new Random(100);
System.out.println("种子为 100 的Random对象");
System.out.println("r3.nextBoolean():\t" + r3.nextBoolean());
System.out.println("r3.nextDouble():\t" + r3.nextDouble());
System.out.println("r3.nextGaussian():\t" + r3.nextGaussian());
}
}
(2)运行结果
第一个种子为 50 的Random对象
r1.nextBoolean(): true
r1.nextDouble(): 0.5978920402252371
r1.nextGaussian(): 1.3268136608950492
----------------------------
第二个种子为 50 的Random对象
r2.nextBoolean(): true
r2.nextDouble(): 0.5978920402252371
r2.nextGaussian(): 1.3268136608950492
----------------------------
种子为 100 的Random对象
r3.nextBoolean(): true
r3.nextDouble(): 0.7346627443280227
r3.nextGaussian(): -1.0560180403978943
从上面运行结果来看,只要两个 Random 对象的种子相同,并且方法的调用顺序也相同(没看错哦 _,如果顺序不一致产生的数也会不同),他们就会产生相同的数字序列。也就是说,Random 产生的数字并不是真正随机的,而是一种伪随机
。
为了避免两个 Random 对象产生相同的数字序列,通常推荐使用当前时间
作为 Random 对象的种子(也就是 Random 的默认种子 ( ̄┰ ̄*))。代码如下所示:
Random rand = new Random(System.currentTimeMillis());
2、ThreadLocalRandom 类
2.1、ThreadLocalRandom 类的介绍
ThreadLocalRandom 类是 Java7 新增的一个类,它是 Random 的增强版。在并发访问的环境
下,使用 ThreadLocalRandom 來代替 Random 可以减少多线程资源竞争
,最终保证系统具有更好的线程安全性
。ThreadLocalRandom 类的用法与 Random 类的用法基本相似,它提供个静态的 current( ) 方法
来获取 ThreadLocalRandom 对象,获取该对象之后即可调用各种 nextXxx( ) 方法来获取伪随机数。
2.2、ThreadLocalRandom 类的使用
(1)代码表示
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomTest {
public static void main(String[] args) {
// 通过静态方法 current() 来获取本地现场的随机对象
ThreadLocalRandom rand = ThreadLocalRandom.current();
// 生成 [4, 20) 之间的随机整数
System.out.println("rand.nextInt(4, 20):\t" + rand.nextInt(4, 20));
// 生成 [2.0, 10.0) 之间的伪随机浮点数
System.out.println("rand.nextDouble(2.0, 10.0):\t" + rand.nextDouble(2.0, 10.0));
}
}
(2)运行结果
rand.nextInt(4, 20): 13
rand.nextDouble(2.0, 10.0): 7.176239930654342