java random源码_Java中Math.random()与Random类生成随机数及源码分析

本文详细介绍了Java中Math.random()方法和Random类生成随机数的原理,包括它们的使用示例、构造方法分析以及两者的关系。Math.random()生成[0,1)之间的随机数,Random类则能生成指定范围内的整数,种子值决定了随机数序列的生成。无参数构造的Random对象使用系统时间作为种子,确保随机性,而固定种子值则会生成可预测的序列。" 127977542,16101544,游戏引擎架构分层解析:平台层与工具层,"['游戏引擎', '图形渲染', '游戏程序', '架构']
摘要由CSDN通过智能技术生成

Math.random()是生成随机选取大于等于0且小于1的伪随机数,也就是说,从0(包含0)往上且不包括1(去除1)的所有范围。

Random类包含有参数和无参数的构造方法,其中无参数的构造方法每次都是使用当前系统时间作为种子,而有参数的构造方法是使用一个固定值(参数)作为种子。每次使用时先创建一个Random对象,称为随机数生成器,然后调用Random.next**()方法获取数值。

Math.random()方法生成随机数

生成一个[0,1)之间的随机数,举例参考代码如下:package com.yoodb.study.other.random;

public class DemoTest01 {

public static void main(String[]args){

System.out.println("通过Math.random产生的随机数列[关注微信公众号“Java精选”]:");

for (int j = 0; j 

System.out.print(Math.random() + ",");

}

}

}

运行结果如下:通过Math.random产生的随机数列[关注微信公众号“Java精选”]:

0.5956019878671859,0.24739500123720504,0.09675226363769507,0.11460305663401749,0.7565292415953803,0.13633278295115547,0.7136188381381711,0.9789645131075377,

生成一个8位的随机整数,参考代码如下:package com.yoodb.study.other.random;

public class DemoTest02 {

public static void main(String[]args){

int rand = (int)(Math.random()*100000000);

System.out.println("生成一个8位的随机整数为:" + rand);

}

}

运行结果如下:生成一个8位的随机整数为:11891302

Random类生成随机数

有参数构造方法:随机数生成器即Random对象,种子的值100。生成[0-n)的数值,也就是包括0,但是不包括n且全都是整数,代码如下:package com.yoodb.study.other.random;

import java.util.Random;

public class DemoTest03 {

public static void main(String[]args){

for(int i = 0; i 

System.out.println("执行第" + (i+1) + "次");

Random random = new  Random(100);

for(int j = 0; j 

System.out.println("生成[0-50)的整数值为:" + random.nextInt(50));

}

}

}

}

运行结果如下:执行第1次

生成[0-50)的整数值为:15

生成[0-50)的整数值为:0

生成[0-50)的整数值为:24

执行第2次

生成[0-50)的整数值为:15

生成[0-50)的整数值为:0

生成[0-50)的整数值为:24

注:当使用有参数的构造创建随机数生成器然后生成随机数序列时,产生的随机数是经过传递的参数计算得到的,具有相同参数的Random对象生成的随机数序列相同。

无参数构造方法:随机数生成器即Random对象,不传递种子。生成[0-n)的数值,也就是包括0,但是不包括n且全都是整数,代码如下:package com.yoodb.study.other.random;

import java.util.Random;

public class DemoTest03 {

public static void main(String[]args){

for(int i = 0; i 

System.out.println("执行第" + (i+1) + "次");

Random random = new  Random();

for(int j = 0; j 

System.out.println("生成[0-50)的整数值为:" + random.nextInt(50));

}

}

}

}

运行结果如下:执行第1次

生成[0-50)的整数值为:44

生成[0-50)的整数值为:45

生成[0-50)的整数值为:38

执行第2次

生成[0-50)的整数值为:40

生成[0-50)的整数值为:34

生成[0-50)的整数值为:14

注:通过无参构造创建Random对象,其本质是也是种子,只不过种子不是具体的数值,而是系统当前的时间,也因此创建的随机数是不相同的。

Random类源码分析

关于Random类,其构造方法源码如下:/**

* Creates a new random number generator. This constructor sets

* the seed of the random number generator to a value very likely

* to be distinct from any other invocation of this constructor.

*/

public Random() {

this(seedUniquifier() ^ System.nanoTime());

}

译:创建新的随机数生成器。此构造方法设置随机数生成器的种子是一个值与此构造方法的任何其他调用不同。

点击this,跳转到对应的有参构造中,显然由代码可以看出种子的生成和当前时间有关系,因此这样生成的种子是唯一的。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);

}

}

Math.random()和Random类两者关系

查看Math类源码,具体如下:...

private static final class RandomNumberGeneratorHolder {

static final Random randomNumberGenerator = new Random();

}

...

public static double random() {

return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();

}

...

从Math类的源码分析可以看出Math.random()方法内部调用的方法就是Random类中的nextDouble()方法,此时可以看出Math.random()返回的是double类型值。

通过比较可以得出结论:

1、随机数是种子经过计算生成的。

2、Random类中不含参的构造方法每次都是使用当前时间作为种子,随机性强;而含有参数的构造方法是以参数为种子产生的伪随机数,更有可预见性。

3、具有相同种子值的Random对象生成的随机数相同;种子值不同,产生的随机数不再一致。

4、Math.random()方法中内部调用的方法是Random类中的nextDouble()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值