【问题标题】:What is the use of the Random(long) constructor?Random(long) 构造函数有什么用?
【发布时间】:2015-09-28 03:23:36
【问题描述】:

Random类有2个构造函数

  1. public Random()
  2. public Random(long seed)

oracle 中第二个构造函数的描述为

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

我没有完全理解。而且我没有找到任何文章/书籍清楚地解释了为什么何时以及如何使用它。

谁能解释一下?

【问题讨论】:

标签: java random


【解决方案1】:

如果你使用带有种子的构造函数,你会得到一个可重复的序列,所以它有利于测试。如果你使用没有种子的构造函数,你不知道会产生什么样的随机数序列。

【讨论】:

  • @SpringLearner seed 是生成其他结果的数字。如果您不指定它,它将很可能从当前时间开始计算。
  • @Pshemo 不,seed 仅表示 PRNG 的初始状态。由于 PRNG 总是从前一个数字生成下一个数字,因此您必须在生成第一个数字之前提供“第零个数字”。这个比喻是基于如何将真正的种子视为植物的初始状态。
  • @biziclop 但这实际上就是我所说的:“生成其他结果的数字”。更准确地说,我可以将“其他结果”更改为“下一个结果”,但公平地说,如果没有以前的结果(在某些时候来自seed :)
  • @Pshemo 你说得对,我在你编辑你的评论之前写了我的评论,我不太清楚你想说什么。对不起。
  • @biziclop 是的,很抱歉造成混淆。
【解决方案2】:

伪随机数生成器的工作原理是根据之前生成的数字重复生成一个新数字。这意味着,如果您始终拥有相同的 first“随机”数,并且使用相同的伪随机数生成器生成第二个,那么您将始终拥有相同的 second “随机”数字也是如此。

第一个Random 构造函数构造了一个带有不确定种子(序列中的第一个数字)的伪随机数生成器,因此您几乎总是会得到不同的“随机”数序列。第二个Random 构造函数用你想要的任何种子构造一个伪随机数生成器,所以如果你给它相同的种子,你总是会得到相同的序列。

这是一个例子。如果您像这样创建Random

Random yourRandom = new Random();

它会从一些种子开始。该种子可能是 42、121、3810 等等。您永远无法确定何时创建它。它生成的所有随机数都基于该种子,因此由于它几乎总是使用不同的种子,因此您几乎总是会从中得到不同的“随机”数。

另一方面,如果您像这样创建Random

Random yourOtherRandom = new Random(36);

yourOtherRandom 生成的所有数字都将从 36 开始计算。由于第一个数字 (36) 相同,第二个数字从第一个数字开始计算,依此类推,yourOtherRandom 生成的所有数字都将相同每次运行程序时。

【讨论】:

  • 抱歉没看懂你的回答,请举个例子
  • 你已经过了 36 岁,这是什么意思?生成的随机数会永远大于 36 还是永远小于 36?
  • @SpringLearner 它不对生成的数字提供任何保证。这只是意味着所有其他数字都将从 36 以某种方式计算出来。该计算可能像加 1 一样简单(不太可能),因此您的序列可能是 36、37、38 等,或者可能是涉及素数和模数的非常复杂的东西(更有可能),因此您的序列可能是像 36、120、23、43747、1572、18、9、5738 等。关键是每个数字都由前一个数字决定。
  • @SpringLearner Building 从那个例子,如果你从 36 开始,下一个数字将是 120,保证。或者如果你从 43747 开始,下一个数字将是 1572,保证。顺序相同;重要的是你从哪里开始。当然,这与Random 生成的序列不同,但原理相同。
  • 我所有的疑惑都还不清楚,但有些已经解开了,+1
【解决方案3】:

这是一个有趣的! 随机数的生成根本不是随机的。如果您使用相同的种子并要求它提供一堆随机数,您将得到相同的序列。这很重要,因为它允许不同的计算机可以预测地生成相同的序列,只要它们共享种子。 如果您不指定种子,那么将为您选择一个世界上任何其他 VM 都不太可能选择的种子。但是,如果有人猜测您使用的种子,他们将能够生成相同的数字序列。

来自谷歌搜索:Random search

【讨论】:

    【解决方案4】:

    Random 生成器是Pseudorandom number generator。这意味着它实际上不是随机数生成器,而只是一些巧妙的算法,可以生成完全确定的数字,看起来像随机的

    使用生成器时,每次生成随机数时,它都会修改其内部状态,以便在下一次调用时生成不同的数字。但是,在开始时必须初始化该算法的内部状态,并且用于该初始化的值通常称为seed。无参数构造函数根据系统时间自行生成种子,而另一个构造函数允许您放置种子,这允许您使其可重复 - 相同的种子(和相同的生成器)将产生相同的数字序列.

    如果您有兴趣,here 是来自 OpenJDK 的Random 类的源代码(即 Java 的开源实现,但它应该在功能上是等效的)。 seed 的构造函数在第 135 行,setSeed 方法在第 168 行,例如nextInt 方法在第 328 行,它只调用一个私有方法 next,它在第 198 行,这是所有魔法发生的地方。它还有 javadoc 参考了这种生成器的(可能更数学的)描述。

    【讨论】:

      【解决方案5】:

      不知道您要问的是关于区分默认构造函数和参数构造函数的问题。当你实例化一个新的 Random 对象时,你可以这样编码:

      Random random=new Random();
      

      这样,我们调用了默认构造函数,即没有参数的构造函数。 但如果你这样编码:

      Random random=new Random(47);
      

      我们调用一个参数为 47 的构造函数。

      类似于C语言;如果您使用相同的种子并且无论何时不会改变,种子将“随机”创建一个数字。但是如果你选择第一种方法,运行一次就会修改数字!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-16
        • 2014-11-08
        • 2011-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多