Java 解惑:Random 种子的作用、含参与不含参构造函数区别
Random 通常用来作为随机数生成器,它有两个构造方法:
Random random = new Random();
Random random2 = new Random(50);
1.不含参构造方法:
public Random() {
setSeed(System.nanoTime() + seedBase);
++seedBase;
}
2.含参构造方法:
public Random(long seed) {
setSeed(seed);
}
都调用的 setSeed 方法:
public synchronized void setSeed(long seed) {
this.seed = (seed ^ multiplier) & ((1L << 48) - 1);
haveNextNextGaussian = false;
}
可以看到,不含参构造方法每次都使用当前时间作为种子,而含参构造方法是以一个固定值作为种子
什么是种子 seed 呢?
seed 是 Random 生成随机数时使用的参数:
Random 中最重要的就是 next(int) 方法,使用 seed 进行计算:
protected synchronized int next(int bits) {
seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1);
return (int) (seed >>> (48 - bits));
}
其他 nextXXX 方法都是调用的 next()。
比如 nextInt(int):
public int nextInt(int n) {
if (n <= 0) {
throw new IllegalArgumentException("n <= 0: " + n);
}
if ((n & -n) == n) {
//调用 next()
return (int) ((n * (long) next(31)) >> 31);
}
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n - 1) < 0);
return val;
}
再比如 nextBoolean():
//也是调用的 next()
public boolean nextBoolean() {
return next(1) != 0;
}
举个栗子:
@Test
public void testRandomParameter(){
System.out.println("Random 不含参构造方法:");
for (int i = 0; i < 5; i++) {
Random random = new Random();
for (int j = 0; j < 8; j++) {
System.out.print(" " + random.nextInt(100) + ", ");
}
System.out.println("");
}
System.out.println("");
System.out.println("Random 含参构造方法:");
for (int i = 0; i < 5; i++) {
Random random = new Random(50);
for (int j = 0; j < 8; j++) {
System.out.print(" " + random.nextInt(100) + ", ");
}
System.out.println("");
}
}
分别用含参构造方法和不含参构造方法创建 5 个随机生成器对象,每个随机生成器再生产 8 个随机数,对比下结果:
再运行一次:
总结:
通过上述例子可以发现:
随机数是种子经过计算生成的。
- 不含参的构造函数每次都使用当前时间作为种子,随机性更强
- 而含参的构造函数其实是伪随机,更有可预见性
Java 解惑:Random 种子的作用、含参与不含参构造函数区别的更多相关文章
- Java Random 含参与不含参构造函数的区别
##Random 通常用来作为随机数生成器,它有两个构造方法: Random random = new Random(); Random random2 = new Random(50); 1.不含参 ...
- java.util.Random深入理解
java.util.Random next方法的原理 比较好的参考文档: http://isky001.iteye.com/blog/1339979 package random.utilrandom ...
- Java:Random函数及其种子的作用
伪随机(preundorandom):通过算法产生的随机数都是伪随机!! 只有通过真实的随机事件产生的随机数才是真随机!!比如,通过机器的硬件噪声产生随机数.通过大气噪声产生随机数 Random生成的 ...
- java中random()函数用法介绍
Random() 创建一个新的随机数生成器. 代码如下 复制代码 Random(long seed) 使用单个 long 种子创建一个新的随机数生成器. 我们可以在构造Random对象的时候指定种子 ...
- tips:Java的Random类和Random函数
tips:Java的Random类和Random函数! 随机数是一个很有趣的东西,在java中可以通过下面这2种方法得到: (1)Random类: Random类是java.util.Random这个 ...
- Java中 Random
Java中的Random()函数 (2013-01-24 21:01:04) 转载▼ 标签: java random 随机函数 杂谈 分类: Java 今天在做Java练习的时候注意到了Java里面的 ...
- Java API —— Random类
1.Random类概述 此类用于产生随机数 如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列. 2.构造 ...
- Java解惑五:类之谜
本文是依据JAVA解惑这本书,做的笔记.电子书见:http://download.csdn.net/detail/u010378705/7527721 谜题46 函数重载的问题. JAVA重载解析过程 ...
- [转] JAVA的Random类
Random类 (java.util) Random类中实现的随机算法是伪随机,也就是有规则的随机.在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要 ...
随机推荐
- 使用 Fresco加载图片
概念: ImagePipeline ——负责从网络.本地图片.Content Provider(内容提供者)或者本地资源那里获取图片,压缩保存在本地存储中和在内存中保存为压缩的图片 Drawee——处 ...
- 你需要知道的三个 CSS3技巧(转)
1. 在CSS中用attr()显示HTML属性值 attr()功能早在CSS 2.1标准中就已经出现,但现在才开始普遍流行.它提供了一个巧妙的方法在CSS中使用HTML标签上的属性,在很多情况下都能帮 ...
- JavaScript学习——判断数据类型总结(转)
一.JS中的数据类型 1.数值型(Number):包括整数.浮点数. 2.布尔型(Boolean) 3.字符串型(String) 4.对象(Object) 5.数组(Array) 6.空值(Null) ...
- ODBC错误处理
ODBC 中的错误处理 ODBC 中的错误是使用来自每个 ODBC 函数调用的返回值和 SQLError 函数或 SQLGetDiagRec 函数的返回值进行报告的.SQLError 函数用于 ODB ...
- 监听TelephonyManager的通话状态来监听手机的所有的来电
import java.io.FileNotFoundException;import java.io.OutputStream;import java.io.PrintStream;import j ...
- RemoveDPC
HOOKSSDT中加入了DPC之后 要取消DPC 首先找到DPCHookSSDT.sys的基地址和大小 通过枚举所有DPC的地址 将在范围之内的DPC定时器全部移除 枚举DPC: WinXP: 1. ...
- 标签视图控制器UITabBarController
标签视图控制器 UITabBarController FirstViewController*first = [[FirstViewController alloc] init]; //创建一个UIT ...
- bzoj 1854: [Scoi2010]游戏
#include<cstdio> #include<iostream> #include<cstring> #define M 2000008 using name ...
- bzoj 2440 简单莫比乌斯反演
题目大意: 找第k个非平方数,平方数定义为一个数存在一个因子可以用某个数的平方来表示 这里首先需要考虑到二分才可以接下来做 二分去查找[1 , x]区间内非平方数的个数,后面就是简单的莫比乌斯反演了 ...
- 通过获取DNS解析的未转义主机名,区分测试环境和正式环境代码
ASP.Net编程中经常有一些代码,测试环境下需要执行,而正式环境下不需要执行(或者反之). 我们经常做的方式是:去掉注释,测试,再注释,再编译上传(或者反之). 现在,不妨试试以下办法: Reque ...