Random

​ 关于java.util中的Random类,Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。

​ 相同种子数的Random对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。这点在生成多个随机数字时需要特别注意。

​ 1、Random对象的生产:

1
2
3
4
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
//该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子数,然后使用这个种子数构造Random对象。
1
2
3
4
5
6
7
8
9
10
public Random(long seed) {
if (getClass() == Random.class)
this.seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overriden setSeed
this.seed = new AtomicLong();
setSeed(seed);
}
}
//该构造方法可以通过制定一个种子数进行创建。种子数只是随机算法的起源数字,和生成的随机数字的区间无关。

​ 2、Random类中的常用方法:

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
public int nextInt() {
return next(32);
}
//该方法的作用是生成一个随机的int值,该值介于int的区间,也就是-231到231-1之间。
public int nextInt(int bound) {
if (bound <= 0)
throw new IllegalArgumentException(BadBound);
int r = next(31);
int m = bound - 1;
if ((bound & m) == 0) // i.e., bound is a power of 2
r = (int)((bound * (long)r) >> 31);
else {
for (int u = r;
u - (r = u % bound) + m < 0;
u = next(31))
;
}
return r;
}
//该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。
public long nextLong() {
// it's okay that the bottom word remains signed.
return ((long)(next(32)) << 32) + next(32);
}
public boolean nextBoolean() {
return next(1) != 0;
}
//该方法的作用是生成一个随机的boolean值,生成true和false的值几率相等,也就是都是50%的几率。
public double nextDouble() {
return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}
//该方法的作用是生成一个随机的double值,数值介于[0,1.0)之间。

​ 3、Random类使用示例

1
2
3
4
5
6
7
double d1 = r.nextDouble();//生成[0,1.0)区间的小数
double d2 = r.nextDouble() * 5;//生成[0,5.0)区间的小数
double d3 = r.nextDouble() * 1.5 + 1;//生成[1,2.5)区间的小数
int n1 = r.nextInt();//int n1 = r.nextInt();
int n2 = r.nextInt(10);//成[0,10)区间的整数
n2 = Math.abs(r.nextInt() % 10);//成[0,10)区间的整数,首先调用nextInt()方法生成一个任意的int数字,该数字和10取余以后生成的数字区间为(-10,10),
//然后再对该区间求绝对值,则得到的区间就是[0,10)了。

​ 4、相同种子数Random对象问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//相同种子数的Random对象,相同次数生成的随机数字是完全相同的,下面是测试的代码:
Random r1 = new Random(10);
Random r2 = new Random(10);
for(int i = 0;i < 2;i++){
System.out.println(r1.nextInt());
System.out.println(r2.nextInt());
}
//在该代码中,对象r1和r2使用的种子数都是10,则这两个对象相同次数生成的随机数是完全相同的。
//如果想避免出现随机数字相同的情况,则需要注意,无论项目中需要生成多少个随机数字,都只使用一个Random对象即可。

​ 5、Random对象生成概率问题

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
public class RandomDemo {
public static void main(String args[]){
int scoreNumber = 1000;
int zero =0, one = 1,two = 2, three = 3,four = 4,five =5;
int zeroTag =0,oneTag =0,twoTag =0,threeTag =0,fourTag =0,fiveTag =0;
Double zeroProportion,oneProportion,twoProportion,threeProportion,fourProportion,fiveProportion;
for(int i = 0;i<scoreNumber;i++){
Random r = new Random();
int number = r.nextInt(6);
if(number==zero){
zeroTag++;
}else if(number==one){
oneTag++;
}else if(number==two){
twoTag++;
}else if(number==three){
threeTag++;
}else if(number==four){
fourTag++;
}else if(number==five){
fiveTag++;
}else{
System.out.println("随机数生成异常");
}
}
zeroProportion = 1.0*zeroTag/scoreNumber;
oneProportion = 1.0*oneTag/scoreNumber;
twoProportion = 1.0*twoTag/scoreNumber;
threeProportion = 1.0*threeTag/scoreNumber;
fourProportion = 1.0*fourTag/scoreNumber;
fiveProportion = 1.0*fiveTag/scoreNumber;
Double total = zeroProportion+oneProportion+twoProportion+threeProportion+fourProportion+fiveProportion;
System.out.println("zeroProportion="+zeroProportion+","+"oneProportion="+oneProportion+","+"twoProportion="+twoProportion+","+"threeProportion="+threeProportion+","+"fourProportion="+fourProportion+","+"fiveProportion="+fiveProportion);
System.out.println("total="+total);
}
}
//当scoreNumber = 1000时
//zeroProportion=0.167,oneProportion=0.158,twoProportion=0.19,threeProportion=0.144,fourProportion=0.169,fiveProportion=0.172,total=1.0
//当scoreNumber = 10000时
//zeroProportion=0.1694,oneProportion=0.169,twoProportion=0.1594,threeProportion=0.1632,fourProportion=0.1708,fiveProportion=0.1682 total=1.0
//当scoreNumber = 1000000时
//zeroProportion=0.16682,oneProportion=0.166072,twoProportion=0.166039,threeProportion=0.167245,fourProportion=0.16649,fiveProportion=0.167334 total=1.0

​ 6、关于Math类中的random方法

​ 其实在Math类中也有一个random方法,该random方法的工作是生成一个[0,1.0)区间的随机小数。通过阅读Math类的源代码可以发现,Math类中的random方法就是直接调用Random类中的nextDouble方法实现的。只是random方法的调用比较简单,所以很多程序员都习惯使用Math类的random方法来生成随机数字。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
Fork me on GitHub