public class Random extends Object implements Serializable
如果使用相同的种子创建两个Random Random
,并且对每个实例进行相同的方法调用序列,则它们将生成并返回相同的数字序列。 为了保证此属性,为Random类Random
。 为了Java代码的绝对可移植性,Java实现必须使用这里所示的所有算法为Random
类。 然而,Random类的子类Random
使用其他算法,只要它们遵守所有方法的一般合同。
Random类实现的Random
使用protected
实用程序方法,每次调用可以提供多达32个伪随机生成位。
许多应用程序会发现方法Math.random()
使用起来更简单。
java.util.Random的java.util.Random
是线程安全的。 但是,跨线程的同时使用java.util.Random
实例可能会遇到争用,从而导致性能下降。 在多线程设计中考虑使用ThreadLocalRandom
。
java.util.Random的java.util.Random
不是加密安全的。 考虑使用SecureRandom
获取一个加密安全的伪随机数生成器,供安全敏感应用程序使用。
Constructor and Description |
---|
Random()
创建一个新的随机数生成器。
|
Random(long seed)
使用单个
long 种子创建一个新的随机数生成器。
|
Modifier and Type | Method and Description |
---|---|
DoubleStream |
doubles()
返回一个有效的无限流的伪随机
double 值,每个值在零(包括)和一(独占)之间。
|
DoubleStream |
doubles(double randomNumberOrigin, double randomNumberBound)
返回一个有效的无限流伪
double 值
double ,每个值都符合给定的起始(包括)和绑定(排他)。
|
DoubleStream |
doubles(long streamSize)
返回一个流,产生给定的
streamSize 伪
double 数值
double ,每个值在零(包括)和一(独占)之间。
|
DoubleStream |
doubles(long streamSize, double randomNumberOrigin, double randomNumberBound)
返回一个流,产生给定的
streamSize 伪
double 数值
double ,每个值符合给定的起始(包括)和绑定(排他)。
|
IntStream |
ints()
返回一个有效的无限流的伪
int 值。
|
IntStream |
ints(int randomNumberOrigin, int randomNumberBound)
返回一个有效的无限流伪
int 值
int ,每个值都符合给定的起始(包括)和绑定(排他)。
|
IntStream |
ints(long streamSize)
返回一个流,产生给定的
streamSize 数
int 值。
|
IntStream |
ints(long streamSize, int randomNumberOrigin, int randomNumberBound)
返回一个流,产生给定的
streamSize 数
int 值,每个符合给定的起始(包括)和绑定(排他)。
|
LongStream |
longs()
返回一个有效的无限流的伪
long 值。
|
LongStream |
longs(long streamSize)
返回一个流,产生给定的
streamSize 数
long 值。
|
LongStream |
longs(long randomNumberOrigin, long randomNumberBound)
返回一个有效的无限流伪
long 值
long ,每个符合给定的起始(包括)和绑定(排他)。
|
LongStream |
longs(long streamSize, long randomNumberOrigin, long randomNumberBound)
返回一个流,产生给定的
streamSize 数
long ,每个符合给定的起始(包括)和绑定(排他)。
|
protected int |
next(int bits)
生成下一个伪随机数。
|
boolean |
nextBoolean()
返回下一个伪随机数,从这个随机数发生器的序列中均匀分布
boolean 值。
|
void |
nextBytes(byte[] bytes)
生成随机字节并将它们放入用户提供的字节数组中。
|
double |
nextDouble()
返回下一个伪随机数,从这个随机数发生器的序列中
0.0 和
1.0 之间的
double 值
0.0 分布。
|
float |
nextFloat()
返回下一个伪随机数,从这个随机数发生器的序列中
0.0 和
1.0 之间的
float 值
0.0 分布。
|
double |
nextGaussian()
从该随机数发生器的序列返回下一个伪随机数,高斯(“正”)分布
double 值,平均值为
0.0 ,标准差为
1.0 。
|
int |
nextInt()
返回下一个伪随机数,从这个随机数发生器的序列中均匀分布
int 值。
|
int |
nextInt(int bound)
返回伪随机的,均匀分布
int 值介于0(含)和指定值(不包括),从该随机数生成器的序列绘制。
|
long |
nextLong()
返回下一个伪,均匀分布
long 从这个随机数生成器的序列值。
|
void |
setSeed(long seed)
使用单个
long 种子设置该随机数生成器的种子。
|
public Random()
public Random(long seed)
long
种子创建新的随机数生成器。
种子是通过方法next(int)
维护的伪随机数发生器的内部状态的初始值。
调用new Random(seed)
相当于:
Random rnd = new Random(); rnd.setSeed(seed);
seed
- 初始种子
setSeed(long)
public void setSeed(long seed)
long
种子设置此随机数生成器的种子。
setSeed
的一般合同是它改变这个随机数生成器对象的状态,使其处于完全相同的状态,就好像刚刚使用参数seed
作为种子创建的那样。
该方法setSeed
由类实现Random
通过原子地更新所述种子
(seed ^ 0x5DEECE66DL) & ((1L << 48) - 1)
并清除haveNextNextGaussian
使用的标志nextGaussian()
。
实施setSeed
由类Random
碰巧只使用48给定的种子的比特。 然而,一般来说,重写方法可以使用long
参数的所有64位作为种子值。
seed
- 初始种子
protected int next(int bits)
next
的一般合同是它返回一个int
值,如果参数bits
在1
和32
(含)之间,那么返回值的许多低位将是(大约)独立选择的比特值,其中每个(约)同样可能是0
或1
。 方法next
由类Random
通过将种子进行原子更新来实现
(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
并返回
(int)(seed >>> (48 - bits))
.
这是由DH Lehmer定义的线性同余伪随机数生成器,由Donald E. Knuth在“计算机编程艺术 ”第3卷: Seminumerical Algorithms ,第3.2.1节中描述。
bits
- 随机位
public void nextBytes(byte[] bytes)
方法nextBytes
由类别Random
,如同通过:
public void nextBytes(byte[] bytes) { for (int i = 0; i < bytes.length; ) for (int rnd = nextInt(), n = Math.min(bytes.length - i, 4); n-- > 0; rnd >>= 8) bytes[i++] = (byte)rnd; }
bytes
- 用随机字节填充的字节数组
NullPointerException
- 如果字节数组为空
public int nextInt()
int
值。
nextInt
的一般合同是一个int
值被伪随机生成并返回。
所有2 32可能的int
值以(大约)相等的概率产生。
方法nextInt
由Random类Random
,好像通过如下:
public int nextInt() { return next(32); }
int
值
public int nextInt(int bound)
int
值介于0(含)和指定值(不包括),从该随机数生成器的序列绘制。
nextInt
的一般合同是指定范围内的int
值被伪随机生成并返回。
所有bound
可能的int
值以(近似)等概率产生。
方法nextInt(int bound)
由类别Random
,如:
public int nextInt(int bound) { if (bound <= 0) throw new IllegalArgumentException("bound must be positive"); if ((bound & -bound) == bound) // i.e., bound is a power of 2 return (int)((bound * (long)next(31)) >> 31); int bits, val; do { bits = next(31); val = bits % bound; } while (bits - val + (bound-1) < 0); return val; }
仅在下面的方法仅仅是独立选择的位的无偏差源时才使用“近似”对冲。 如果它是随机选择位的完美来源,则所示的int
将从所述范围中选择int
值,具有完美的均匀性。
该算法有点棘手。 它拒绝会导致分配不均的价值(由于2 ^ 31不能被n整除)。 值被拒绝的概率取决于n。 最坏的情况是n = 2 ^ 30 + 1,拒绝概率为1/2,循环终止前的预期迭代次数为2。
该算法处理n特别是2的幂的情况:它从底层伪随机数发生器返回正确数量的高阶位。 在没有特殊处理的情况下,将返回正确数量的低位 。 已知线性同余伪随机数发生器(例如由该类实现的)产生器在其低阶位的值序列中具有短周期。 因此,如果n是2的小功率,这种特殊情况大大增加了对该方法的连续调用返回的值的序列的长度。
bound
- 上限(独占)。
必须是积极的。
int
到零(包括)和
bound
(排他)之间的值int
IllegalArgumentException
- 如果绑定
IllegalArgumentException
public long nextLong()
long
值。
nextLong
的一般合同是一个long
值被伪随机生成并返回。
方法nextLong
由类别Random
,如:
public long nextLong() { return ((long)next(32) << 32) + next(32); }
因为Random
类使用只有48位的种子,所以该算法将不会返回所有可能的long
值。
long
值
public boolean nextBoolean()
boolean
值。
nextBoolean
的一般合同是一个boolean
值被伪随机生成并返回。
价值true
和false
以(大概)相等的概率产生。
方法nextBoolean
由类别Random
,如:
public boolean nextBoolean() { return next(1) != 0; }
boolean
值
public float nextFloat()
float
之间的值0.0
和1.0
从这个随机数生成器的序列。
nextFloat
的一般合同是一个float
值,从0.0f
(含)到1.0f
(独占)一起选择(大致)均匀,被伪随机生成并返回。 以(大致)等概率产生形式m× 2 -24的全部2 24个可能的float
值,其中m是小于2 24的正整数。
方法nextFloat
由Random类Random
,如同通过:
public float nextFloat() { return next(24) / ((float)(1 << 24)); }
仅在下面的方法仅仅是独立选择的位的无偏差源时才使用“近似”对冲。 如果它是随机选择位的完美来源,则所示的float
将从所述范围中选择float
值,具有完美的均匀性。
[在Java的早期版本中,结果错误地计算为:
return next(30) / ((float)(1 << 30));
这可能似乎是等同的,如果不是更好,但实际上它引入了一个轻微的不均匀性,因为浮点数的四舍五入的偏差:有意义的低位比较有可能是0这将是1.]
float
值
0.0
和
1.0
之间
public double nextDouble()
0.0
和1.0
之间的double
值。
nextDouble
的一般合同是从0.0d
(含)到1.0d
(排他)范围内选择(近似均匀)的一个double
值被伪随机生成并返回。
方法nextDouble
由类别Random
,如:
public double nextDouble() { return (((long)next(26) << 27) + next(27)) / (double)(1L << 53); }
因为next
方法只是大致上独立选择的位的无偏差源,所以在next
的描述中使用了“大约”对冲。 如果它是随机选择的位的完美来源,则所示的double
将从所述范围中选择double
值,具有完美的均匀性。
[在Java的早期版本中,结果错误地计算为:
return (((long)next(27) << 27) + next(27)) / (double)(1L << 54);
这可能似乎是等同的,如果不是更好,但事实上它引入了一个大的不均匀性,因为浮点数的四舍五入有偏差:有效位的低位是0的可能性是三倍比那会是1!
这种不均匀性在实践中可能无关紧要,但我们力求完美。]
0.0
和
1.0
之间的
double
值
0.0
分布
Math.random()
public double nextGaussian()
double
值,平均值为0.0
,标准差为1.0
。
nextGaussian
的一般合同是从(大约)平均值0.0
和标准偏差1.0
的常规正态分布中选出一个double
值,被伪随机生成并返回。
方法nextGaussian
由类Random
,好像通过以下的线程安全版本:
private double nextNextGaussian; private boolean haveNextNextGaussian = false; public double nextGaussian() { if (haveNextNextGaussian) { haveNextNextGaussian = false; return nextNextGaussian; } else { double v1, v2, s; do { v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0 v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0 s = v1 * v1 + v2 * v2; } while (s >= 1 || s == 0); double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s); nextNextGaussian = v2 * multiplier; haveNextNextGaussian = true; return v1 * multiplier; } }
这使用GEP Box,ME Muller和G. Marsaglia的极性方法 ,如Donald E. Knuth在“计算机编程艺术 ”第3卷: 半数学算法 ,第3.4.1节,C节,算法P中所述。请注意它生成两个独立的值,只需一次呼叫StrictMath.log
,一次呼叫到StrictMath.sqrt
。
double
值,平均值为
0.0
,标准差
1.0
为该随机数发生器序列
public IntStream ints(long streamSize)
streamSize
- 要生成的值的数量
int
值
IllegalArgumentException
- 如果
streamSize
小于零
public IntStream ints()
ints(Long.MAX_VALUE)
。
int
值
public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound)
streamSize
伪int
数值int
,每个值符合给定的起始(包括)和绑定(排他)。
伪随机int
值被生成,就像它是使用原始和绑定调用以下方法的结果一样:
int nextInt(int origin, int bound) { int n = bound - origin; if (n > 0) { return nextInt(n) + origin; } else { // range not representable as int int r; do { r = nextInt(); } while (r < origin || r >= bound); return r; } }
streamSize
- 要生成的值的数量
randomNumberOrigin
- 每个随机值的起始(含)
randomNumberBound
- 每个随机值的绑定(排他)
int
的流量
int
,每个都有给定的来源(包括)和绑定(排他)
IllegalArgumentException
- 如果
streamSize
小于零,或
randomNumberOrigin
大于等于
randomNumberBound
public IntStream ints(int randomNumberOrigin, int randomNumberBound)
int
值,每个符合给定的起始(包括)和绑定(排他)。
伪随机int
值被生成,就像它是使用原点和边界调用以下方法的结果一样:
int nextInt(int origin, int bound) { int n = bound - origin; if (n > 0) { return nextInt(n) + origin; } else { // range not representable as int int r; do { r = nextInt(); } while (r < origin || r >= bound); return r; } }
ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)
。
randomNumberOrigin
- 每个随机值的起点(含)
randomNumberBound
- 每个随机值的绑定(排他)
int
流(int),每个都有给定的来源(包括)和绑定(排他)
IllegalArgumentException
- 如果
randomNumberOrigin
大于或等于
randomNumberBound
public LongStream longs(long streamSize)
streamSize
数long
数值。
伪随机long
值被生成,就像调用方法nextLong()
的结果一样 。
streamSize
- 要生成的值的数量
long
值
IllegalArgumentException
- 如果
streamSize
小于零
public LongStream longs()
long
值。
伪随机long
值被生成,就像调用方法nextLong()
的结果一样 。
longs(Long.MAX_VALUE)
。
long
值
public LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound)
streamSize
数long
,每个符合给定的起始(包括)和绑定(排他)。
伪随机long
值被生成,就像它是使用原点和边界调用以下方法的结果一样:
long nextLong(long origin, long bound) { long r = nextLong(); long n = bound - origin, m = n - 1; if ((n & m) == 0L) // power of two r = (r & m) + origin; else if (n > 0L) { // reject over-represented candidates for (long u = r >>> 1; // ensure nonnegative u + m - (r = u % n) < 0L; // rejection check u = nextLong() >>> 1) // retry ; r += origin; } else { // range not representable as long while (r < origin || r >= bound) r = nextLong(); } return r; }
streamSize
- 要生成的值的数量
randomNumberOrigin
- 每个随机值的起点(含)
randomNumberBound
- 每个随机值的绑定(排他)
long
流long,每个都有给定的来源(包括)和绑定(排他)
IllegalArgumentException
- 如果
streamSize
小于零,或
randomNumberOrigin
大于或等于
randomNumberBound
public LongStream longs(long randomNumberOrigin, long randomNumberBound)
long
值long
,每个值都符合给定的起始(包括)和绑定(排他)。
伪随机long
值被生成,就像是使用原点和边界调用以下方法的结果一样:
long nextLong(long origin, long bound) { long r = nextLong(); long n = bound - origin, m = n - 1; if ((n & m) == 0L) // power of two r = (r & m) + origin; else if (n > 0L) { // reject over-represented candidates for (long u = r >>> 1; // ensure nonnegative u + m - (r = u % n) < 0L; // rejection check u = nextLong() >>> 1) // retry ; r += origin; } else { // range not representable as long while (r < origin || r >= bound) r = nextLong(); } return r; }
longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)
。
randomNumberOrigin
- 每个随机值的起点(含)
randomNumberBound
- 每个随机值的绑定(排他)
long
流(long),每个都有给定的来源(包括)和绑定(排他)
IllegalArgumentException
- 如果
randomNumberOrigin
大于或等于
randomNumberBound
public DoubleStream doubles(long streamSize)
streamSize
数double
值,每个值在零(包括)和一(独占)之间。
伪随机double
值被生成,就像调用方法nextDouble()
的结果一样 。
streamSize
- 要生成的值的数量
double
值
IllegalArgumentException
- 如果
streamSize
小于零
public DoubleStream doubles()
double
值,每个值在零(包括)和一(独占)之间。
伪随机double
值被生成,就像调用方法nextDouble()
的结果一样 。
doubles(Long.MAX_VALUE)
。
double
值
public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound)
streamSize
伪double
数值double
,每个值符合给定的起始(包括)和绑定(排他)。
伪随机double
值被生成,就好像它是使用原点和边界调用以下方法的结果一样:
double nextDouble(double origin, double bound) { double r = nextDouble(); r = r * (bound - origin) + origin; if (r >= bound) // correct for rounding r = Math.nextDown(bound); return r; }
streamSize
- 要生成的值的数量
randomNumberOrigin
- 每个随机值的起始(含)
randomNumberBound
- 每个随机值的绑定(排他)
double
流(double),每个都有给定的来源(包括)和绑定(排他)
IllegalArgumentException
- 如果
streamSize
小于零
IllegalArgumentException
- 如果
randomNumberOrigin
大于等于
randomNumberBound
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound)
double
值double
,每个值都符合给定的起始(包括)和绑定(排除)。
伪随机double
值被生成,就像它是使用原点和边界调用以下方法的结果一样:
double nextDouble(double origin, double bound) { double r = nextDouble(); r = r * (bound - origin) + origin; if (r >= bound) // correct for rounding r = Math.nextDown(bound); return r; }
doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)
。
randomNumberOrigin
- 每个随机值的起始(含)
randomNumberBound
- 每个随机值的绑定(排他)
double
流double,每个都有给定的起源(包括)和绑定(独占)
IllegalArgumentException
- 如果
randomNumberOrigin
大于或等于
randomNumberBound