首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当我设置种子时,Java random总是返回相同的数字?

当我设置种子时,Java random总是返回相同的数字?
EN

Stack Overflow用户
提问于 2011-04-04 07:19:52
回答 6查看 89K关注 0票数 30

我需要帮助与随机数生成器,我正在创建。我的代码如下(在一个名为numbers的类中):

代码语言:javascript
复制
public int random(int i){
    Random randnum = new Random();
    randnum.setSeed(123456789);
    return randnum.nextInt(i);
}

当我从另一个类调用这个方法时(为了生成一个随机数),它总是返回相同的数。例如,如果我要这样做:

代码语言:javascript
复制
System.out.println(numbers.random(10));
System.out.print(numbers.random(10));

它总是打印相同的数字,例如5 5。我要怎么做才能打印两个不同的数字?例如5 8

我必须设置种子。

谢谢

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-04-04 07:22:56

您需要在整个类中共享Random()实例:

代码语言:javascript
复制
public class Numbers {
    Random randnum;

    public Numbers() {
        randnum = new Random();
        randnum.setSeed(123456789);
    }

    public int random(int i){
        return randnum.nextInt(i);
    }
}
票数 52
EN

Stack Overflow用户

发布于 2011-04-04 07:21:25

如果你总是设置种子,你将总是得到相同的答案。这就是设置种子的功能。

票数 40
EN

Stack Overflow用户

发布于 2012-07-29 07:58:11

有两个问题导致了您看到的结果。第一个是代码为Random实例设置一个种子值。第二种方法是实例方法" Random“实例化一个新的Random对象,然后每次都用相同的种子立即设置它的种子。这两者的结合保证了,对于相同的i值,方法"random“将始终返回相同的值,并且它将始终是种子生成的序列中的第一个。

假设设置种子是强制性的,为了每次都获得序列中的下一个值而不是序列中相同的第一个值,Random的randnum实例不能在调用它的下一个方法之前每次都设置它的种子。要解决这个问题,可以将Random的随机局部变量实例从random实例方法的作用域移动到类作用域。其次,仅当为random分配了Random实例时才设置种子,或者仅当从随机实例中获得相同序列的结果时才设置种子,以便重新开始。随机类的setSeed(长种子)实例方法不能在类作用域中执行,因此构造函数必须使用带有长种子参数的随机构造函数来设置它。下面的代码显示了这些更改:

代码语言:javascript
复制
public class RandomDemo { // arbitrary example class name
    // lots of class related stuff may be here...

    // still inside the class scope...
    // private is a good idea unless an external method needs to change it
    private Random randnum = new Random(123456789L);
    // the seed guarantees it will always produce the same sequence
    // of pseudo-random values when the next methods get called
    // for unpredicable sequences, use the following constructor instead:
    // private Random randnum = new Random();

    // lots of code may be here...

    // publicly exposed instance method for getting random number
    // from a sequence determined by seed 123456789L
    // in the range from 0 through i-1
    public int randnum(int i) {
        // don't set the seed in here, or randnum will return the exact same integer
        // for the same value of i on every method call
        // nextInt(i) will give the next value from randnum conforming to range i
        return randnum.nextInt(i);
    } // end randnum

    // lots of more code may be here...

} // end class RandDemo

如上所述,上述方法将为您的确切问题提供准确的解决方案。然而,考虑到强制种子的作用,使用强制种子似乎并不常见。

如果这是用于类项目或软件测试,其中序列必须是可预测和可重复的,则将种子设置为固定值是有意义的。否则,质疑将种子设置为某个预定值的有效性。下面解释更多关于随机、随机种子以及为什么有提供种子的规定。

Random有两个构造函数:

代码语言:javascript
复制
Random()

代码语言:javascript
复制
Random(long seed)

和一个实例方法

代码语言:javascript
复制
setSeed(long seed)

所有这些都会影响从Random实例获得的数字序列。实例方法,

代码语言:javascript
复制
setSeed(long seed)

将Random对象设置为与其仅使用与构造函数参数相同的种子实例化时所处的相同状态。仅使用种子值的低48位。

如果随机对象实例化时没有种子,则种子将与系统时间相同(以毫秒为单位)。这确保了,除非在同一毫秒内实例化两个随机对象,否则它们将产生不同的伪随机序列。仅使用种子值的低48位。这会导致不可预测的伪随机序列。每次调用next方法时都要获得一个新的Random实例,这是不必要的,也不是浪费计算资源。

提供了Random的种子参数,以便可以实例化一个随机对象,该对象产生一个可重复的序列。对于给定的种子,无论何时使用该种子,next方法中的值序列都保证是相同的序列。这对于将要使用伪随机序列的测试软件很有用,其中结果必须是可预测和可重复的。它对于在操作中创建不同的不可预测伪随机序列没有用处。

“设置种子是强制性的”这句话否定了Random对象的伪随机序列的任何不可预测性。这是否适用于类、项目或软件测试,在这些测试中,程序的相同输入结果必须相同?

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5533191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档