阅读(3435) (0)

鸿蒙OS Random

2022-06-16 16:27:50 更新

Random

java.lang.Object

|---java.util.Random

public class Random
extends Object
implements Serializable

此类的一个实例用于生成伪随机数流。 该类使用 48 位种子,该种子使用线性同余公式进行修改。

如果使用相同的种子创建 Random 的两个实例,并且为每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。 为了保证这一特性,为类 Random 指定了特定的算法。 为了 Java 代码的绝对可移植性,Java 实现必须使用此处为类 Random 显示的所有算法。 但是,允许类 Random 的子类使用其他算法,只要它们遵守所有方法的通用合同。

类 Random 实现的算法使用受保护的实用程序方法,该方法在每次调用时可以提供多达 32 个伪随机生成的位。

许多应用程序会发现 Math#random 方法更易于使用。

java.util.Random 的实例是线程安全的。 但是,跨线程并发使用同一个 java.util.Random 实例可能会遇到争用,从而导致性能下降。 考虑改为在多线程设计中使用 ThreadLocalRandom。

java.util.Random 的实例在密码学上不是安全的。 考虑改为使用 SecureRandom 来获取加密安全的伪随机数生成器,以供安全敏感的应用程序使用。

构造函数摘要

构造函数 描述
Random() 创建一个新的随机数生成器。
Random(long seed) 使用单个长种子创建一个新的随机数生成器。

方法总结

修饰符和类型 方法 描述
DoubleStream doubles() 返回一个有效无限的伪随机双精度值流,每个值介于零(包括)和一(不包括)之间。
DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) 返回一个有效无限的伪随机双精度值流,每个都符合给定的原点(包括)和绑定(不包括)。
DoubleStream doubles(long streamSize) 返回一个流,该流产生给定的 streamSize 数量的伪随机双精度值,每个值介于零(包括)和一(不包括)之间。
DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) 返回产生给定 streamSize 数量的伪随机双精度值的流,每个都符合给定的原点(包括)和绑定(不包括)。
IntStream ints() 返回一个有效无限的伪随机 int 值流。
IntStream ints(int randomNumberOrigin, int randomNumberBound) 返回一个有效无限的伪随机 int 值流,每个值都符合给定的原点(包括)和绑定(不包括)。
IntStream ints(long streamSize) 返回产生给定 streamSize 数量的伪随机 int 值的流。
IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) 返回一个流,该流产生给定的 streamSize 数量的伪随机 int 值,每个都符合给定的原点(包括)和边界(不包括)。
LongStream longs() 返回一个有效无限的伪随机长值流。
LongStream longs(long streamSize) 返回产生给定 streamSize 数量的伪随机 long 值的流。
LongStream longs(long randomNumberOrigin, long randomNumberBound) 返回一个有效无限的伪随机长值流,每个值都符合给定的原点(包括)和绑定(不包括)。
LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound) 返回产生给定 streamSize 数量的伪随机 long 的流,每个都符合给定的原点(包括)和绑定(不包括)。
protected int next(int bits) 生成下一个伪随机数。
boolean nextBoolean() 从该随机数生成器的序列中返回下一个伪随机、均匀分布的布尔值。
void nextBytes(byte[] bytes) 生成随机字节并将它们放入用户提供的字节数组中。
double nextDouble() 从该随机数生成器的序列中返回 0.0 到 1.0 之间的下一个伪随机、均匀分布的双精度值。
float nextFloat() 从该随机数生成器的序列中返回下一个伪随机、均匀分布的浮点值,介于 0.0 和 1.0 之间。
double nextGaussian() 从该随机数生成器的序列返回下一个伪随机、高斯(“正常”)分布双精度值,均值为 0.0,标准差为 1.0。
int nextInt() 从该随机数生成器的序列中返回下一个伪随机、均匀分布的 int 值。
int nextInt(int bound) 返回一个伪随机、均匀分布的 int 值,介于 0(包括)和指定值(不包括)之间,取自该随机数生成器的序列。
long nextLong() 从这个随机数生成器序列返回下一个伪随机、均匀分布的长值。
void setSeed(long seed) 使用单个长种子设置此随机数生成器的种子。
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

构造函数详细信息

Random

public Random()

创建一个新的随机数生成器。 此构造函数将随机数生成器的种子设置为一个很可能与此构造函数的任何其他调用不同的值。

Random

public Random(long seed)

使用单个长种子创建一个新的随机数生成器。 种子是伪随机数生成器内部状态的初始值,由方法 next(int) 维护。

调用 new Random(seed) 等效于:

 Random rnd = new Random();
 rnd.setSeed(seed);

参数:

参数名称 参数描述
seed 初始种子

方法详情

setSeed

public void setSeed(long seed)

使用单个长种子设置此随机数生成器的种子。 setSeed 的一般约定是,它会更改此随机数生成器对象的状态,使其处于与刚刚使用参数种子作为种子创建时完全相同的状态。 方法 setSeed 由 Random 类通过原子更新种子来实现

(seed ^ 0x5DEECE66DL) & ((1L << 48) - 1)

并清除 nextGaussian() 使用的 haveNextNextGaussian 标志。

由 Random 类实现的 setSeed 恰好只使用给定种子的 48 位。 然而,一般来说,覆盖方法可以使用长参数的所有 64 位作为种子值。

参数:

参数名称 参数描述
seed 初始种子

next

protected int next(int bits)

生成下一个伪随机数。 子类应该覆盖它,因为它被所有其他方法使用。

next 的一般约定是它返回一个 int 值,如果参数位在 1 到 32(含)之间,那么返回值的许多低位将(大约)独立选择的位值,其中每个 是(大约)同样可能是 0 或 1。方法 next 由 Random 类通过原子更新种子来实现

(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)

并返回

(int)(seed >>> (48 - bits)).

这是一个线性同余伪随机数生成器,由 D. H. Lehmer 定义并由 Donald E. Knuth 在计算机编程艺术,第 3 卷:半数值算法,第 3.2.1 节中描述。

参数:

参数名称 参数描述
bits 随机位

返回:

此随机数生成器序列中的下一个伪随机值

nextBytes

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 要填充随机字节的字节数组

Throws:

Throw名称 Throw描述
NullPointerException 如果字节数组为空

nextInt

public int nextInt()

从该随机数生成器的序列中返回下一个伪随机、均匀分布的 int 值。 nextInt 的一般约定是伪随机生成并返回一个 int 值。 所有 232 个可能的 int 值都是以(大约)相等的概率产生的。

nextInt 方法由 Random 类实现,就像通过:

  public int nextInt() {
   return next(32);
 }

返回:

此随机数生成器序列中的下一个伪随机、均匀分布的 int 值

nextInt

public int nextInt(int bound)

返回一个伪随机、均匀分布的 int 值,介于 0(包括)和指定值(不包括)之间,取自该随机数生成器的序列。 nextInt 的一般约定是伪随机生成并返回指定范围内的一个 int 值。 所有绑定的可能 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 值。

该算法有点棘手。 它拒绝会导致分布不均匀的值(因为 2^31 不能被 n 整除)。 一个值被拒绝的概率取决于 n。 最坏的情况是 n=2^30+1,拒绝的概率是 1/2,循环终止前的预期迭代次数是 2。

该算法特别处理 n 是 2 的幂的情况:它从底层伪随机数生成器返回正确数量的高位。 在没有特殊处理的情况下,将返回正确数量的低位。 已知线性同余伪随机数生成器(例如由此类实现的那个)在其低位的值序列中具有短周期。 因此,如果 n 是 2 的小幂,这种特殊情况会大大增加连续调用此方法返回的值序列的长度。

参数:

参数名称 参数描述
bound 上限(不包括)。 必须是积极的。

返回:

此随机数生成器序列的下一个伪随机、均匀分布的 int 值,介于零(包括)和边界(不包括)之间

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 bound 不是正数

nextLong

public long nextLong()

从这个随机数生成器的序列中返回下一个伪随机、均匀分布的 long 值。 nextLong 的一般合约是伪随机生成并返回一个 long 值。

nextLong 方法由 Random 类实现,就像通过:

  public long nextLong() {
   return ((long)next(32) << 32) + next(32);
 }

因为 Random 类使用只有 48 位的种子,所以该算法不会返回所有可能的 long 值。

返回:

此随机数生成器序列中的下一个伪随机、均匀分布的长值

nextBoolean

public boolean nextBoolean()

从该随机数生成器的序列中返回下一个伪随机、均匀分布的布尔值。 nextBoolean 的一般约定是伪随机生成并返回一个布尔值。 值 true 和 false 以(大约)相等的概率产生。

nextBoolean 方法由 Random 类实现,就像通过:

  public boolean nextBoolean() {
   return next(1) != 0;
 }

返回:

此随机数生成器序列中的下一个伪随机、均匀分布的布尔值

nextFloat

public float nextFloat()

从该随机数生成器的序列中返回下一个伪随机、均匀分布的浮点值,介于 0.0 和 1.0 之间。

nextFloat 的一般约定是从 0.0f(包括)到 1.0f(不包括)范围内(大约)均匀选择的一个浮点值是伪随机生成并返回的。 m x 2-24 形式的所有 224 个可能的浮点值(其中 m 是小于 224 的正整数)以(大约)相等的概率产生。

nextFloat 方法由 Random 类实现,就像通过:

  public float nextFloat() {
   return next(24) / ((float)(1 << 24));
 }

在前面的描述中使用对冲“大约”只是因为下一个方法只是大约独立选择位的无偏源。 如果它是随机选择的位的完美来源,那么所示的算法将从规定的范围内选择具有完美一致性的浮点值。

[在 Java 的早期版本中,结果被错误地计算为:

    return next(30) / ((float)(1 << 30));

这似乎是等效的,如果不是更好的话,但实际上由于浮点数舍入的偏差,它引入了轻微的不均匀性:有效数字的低位为 0 的可能性略高于 它将是 1。]

返回:

此随机数生成器序列中的下一个伪随机、均匀分布的浮点值,介于 0.0 和 1.0 之间

nextDouble

public double nextDouble()

从该随机数生成器的序列中返回 0.0 到 1.0 之间的下一个伪随机、均匀分布的双精度值。

nextDouble 的一般约定是从 0.0d(包括)到 1.0d(不包括)范围内(大约)均匀选择的一个 double 值是伪随机生成并返回的。

nextDouble 方法由 Random 类实现,就像这样:

  public double nextDouble() {
   return (((long)next(26) << 27) + next(27))
     / (double)(1L << 53);
 }

在前面的描述中使用对冲“大约”只是因为下一个方法只是大约独立选择位的无偏源。 如果它是随机选择的位的完美来源,那么所示的算法将从规定的范围中选择具有完美一致性的双精度值。

[在 Java 的早期版本中,结果被错误地计算为:

    return (((long)next(27) << 27) + next(27))
     / (double)(1L << 54);

这似乎是等效的,如果不是更好的话,但实际上由于浮点数舍入的偏差,它引入了很大的不均匀性:有效数字的低位为 0 的可能性是其三倍 比那将是1! 这种不均匀性在实践中可能并不重要,但我们力求完美。]

返回:

此随机数生成器序列中的下一个伪随机、均匀分布的双精度值,介于 0.0 和 1.0 之间

nextGaussian

public double nextGaussian()

从该随机数生成器的序列返回下一个伪随机、高斯(“正常”)分布双精度值,均值为 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;
   }
 }

这使用 G. E. P. Box、M. E. Muller 和 G. Marsaglia 的极坐标方法,如 Donald E. Knuth 在计算机编程艺术第 3 卷:半数值算法,第 3.4.1 节,C 小节,算法 P 中所述。请注意, 它仅以一次调用 StrictMath.log 和一次调用 StrictMath.sqrt 为代价生成两个独立的值。

返回:

下一个伪随机,高斯(“正常”)分布的双精度值,均值为 0.0,标准差为 1.0,来自该随机数生成器的序列

ints

public IntStream ints(long streamSize)

返回产生给定 streamSize 数量的伪随机 int 值的流。

生成一个伪随机 int 值,就好像它是调用方法 nextInt() 的结果一样。

参数:

参数名称 参数描述
streamSize 要生成的值的数量

返回:

伪随机 int 值流

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 streamSize 小于零

ints

public IntStream ints()

返回一个有效无限的伪随机 int 值流。

生成一个伪随机 int 值,就好像它是调用方法 nextInt() 的结果一样。

返回:

伪随机 int 值流

ints

public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound)

返回一个流,该流产生给定的 streamSize 数量的伪随机 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 值流,每个值都具有给定的原点(包括)和边界(不包括)

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 streamSize 小于零,或者 randomNumberOrigin 大于或等于 randomNumberBound

ints

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;
   }
 }

参数:

参数名称 参数描述
randomNumberOrigin 每个随机值的原点(包括)
randomNumberBound 每个随机值的界限(不包括)

返回:

一个伪随机 int 值流,每个值都具有给定的原点(包括)和边界(不包括)

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 randomNumberOrigin 大于或等于 randomNumberBound

longs

public LongStream longs(long streamSize)

返回产生给定 streamSize 数量的伪随机 long 值的流。

生成一个伪随机长值,就好像它是调用方法 nextLong() 的结果。

参数:

参数名称 参数描述
streamSize 要生成的值的数量

返回:

伪随机 long 值流

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 streamSize 小于零

longs

public LongStream longs()

返回一个有效无限的伪随机长值流。

生成一个伪随机长值,就好像它是调用方法 nextLong() 的结果。

返回:

伪随机 long 值流

longs

public LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound)

返回产生给定 streamSize 数量的伪随机 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 值流,每个值都具有给定的原点(包括)和边界(不包括)

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 streamSize 小于零,或者 randomNumberOrigin 大于或等于 randomNumberBound

longs

public LongStream longs(long randomNumberOrigin, long randomNumberBound)

返回一个有效无限的伪随机长值流,每个值都符合给定的原点(包括)和绑定(不包括)。

生成一个伪随机长值,就好像它是使用源和绑定调用以下方法的结果:

  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;
 }

参数:

参数名称 参数描述
randomNumberOrigin 每个随机值的原点(包括)
randomNumberBound 每个随机值的界限(不包括)

返回:

一个伪随机 long 值流,每个值都具有给定的原点(包括)和边界(不包括)

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 randomNumberOrigin 大于或等于 randomNumberBound

doubles

public DoubleStream doubles(long streamSize)

返回一个流,该流产生给定的 streamSize 数量的伪随机双精度值,每个值介于零(包括)和一(不包括)之间。

生成一个伪随机双精度值,就好像它是调用方法 nextDouble() 的结果。

参数:

参数名称 参数描述
streamSize 要生成的值的数量

返回:

double 值流

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 streamSize 小于零

doubles

public DoubleStream doubles()

返回一个有效无限的伪随机双精度值流,每个值介于零(包括)和一(不包括)之间。

生成一个伪随机双精度值,就好像它是调用方法 nextDouble() 的结果。

返回:

伪随机 double 值流

doubles

public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound)

返回产生给定 streamSize 数量的伪随机双精度值的流,每个都符合给定的原点(包括)和边界(不包括)。

生成一个伪随机双精度值,就好像它是使用原点和绑定调用以下方法的结果:

  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 值流,每个都有给定的原点(包括)和边界(不包括)

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 streamSize 小于零
IllegalArgumentException 如果 randomNumberOrigin 大于或等于 randomNumberBound

doubles

public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound)

返回一个有效无限的伪随机双精度值流,每个都符合给定的原点(包括)和绑定(不包括)。

生成一个伪随机双精度值,就好像它是使用原点和绑定调用以下方法的结果:

  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;
 }

参数:

参数名称 参数描述
randomNumberOrigin 每个随机值的原点(包括)
randomNumberBound 每个随机值的界限(不包括)

返回:

一个伪随机 double 值流,每个都有给定的原点(包括)和边界(不包括)

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果 randomNumberOrigin 大于或等于 randomNumberBound