Java 随机生成器的种子产生不同的输出



尝试使用两个特定种子创建创建时传递到对象的情况下创建硬币对象类时,我注意到当将种子传递到int" seed"时,种子变量会产生与仅将特定数字输入到随机数生成器中的变量不同。这是硬币类中的一些代码:

public int headCount;
public int tailCount;
public int seed;
public Coin( int n ){
    seed = n;
    headCount = 0;
    tailCount = 0;
}
public Random flipGenerator = new Random(seed); 
public String flip(){
    String heads = "H";
    String tails = "T";
    boolean nextFlip = flipGenerator.nextBoolean();
    if (nextFlip == true)
    {
        headCount++;
        return heads;
    }
    if (nextFlip == false)
    {
        tailCount++;
        return tails;
    }
    return null;
}

以下是创建和打印硬币对象的文件:

Coin coin1 = new Coin( 17 );
Coin coin2 = new Coin( 13 ); 

该文件中的代码使用17个种子将随机翻转的结果打印出20次,使用13种子,最后35次,再次使用17个种子。但是,使用

时输出不正确
public Random flipGenerator = new Random(seed); 

而不是

public Random flipGenerator = new Random(17);

public Random flipGenerator = new Random(13);  

为什么会发生?

实例字段是在调用构造函数之前初始初始化的。

根据执行顺序,此代码:

public int headCount;
public int tailCount;
public int seed;
public Coin( int n ){
    seed = n;
    headCount = 0;
    tailCount = 0;
}
public Random flipGenerator = new Random(seed); 

在功能上等效于此:

public int headCount;
public int tailCount;
public int seed;
public Random flipGenerator = new Random(seed); 
public Coin( int n ){
    seed = n;
    headCount = 0;
    tailCount = 0;
}

在Java中,任何未明确初始化的字段均给出零/null/false的值,因此您是始终执行flipGenerator = new Random(0)。当您在构造函数中初始化seed时,已经创建了随机对象。实例字段在构造函数无关紧要之后声明,因为所有实例字段及其初始化表达式均在调用构造函数之前执行。

每当您初始化Coin类时,它将使用0作为种子。无论是否将flipGenerator初始化放在构造函数下方,它仍然会在构造函数中调用,因为它是一个实例变量。

Coin coin1 = new Coin( 17 );
Coin coin2 = new Coin( 13 ); 

此代码使用0,因为当您通过种子时,将flipgenerator用0。

的默认种子初始化。

您需要执行此操作

    public int headCount;
    public int tailCount;
    public int seed;
    public Random flipGenerator;
    public Coin( int n ){
        seed = n;
        headCount = 0;
        tailCount = 0;
        flipGenerator = new Random(seed);
    }
  ...
}

最新更新