当我运行以下代码时,无论我在for循环中使用什么范围,该代码始终会打印出true十次。

public static void main(String[] args)
{
    Random bool = new Random();

    for (int i = 0; i < 10; i++) {
        bool.setSeed(i);
        System.out.println(bool.nextBoolean());
    }
}

但是,如果我稍稍更改了代码,并让随机生成器在打印前运行一次nextBoolean()函数,则我在输出中得到了truefalse的正态分布,当更改for循环的范围时,该分布会增大:
public static void main(String[] args)
{
    Random bool = new Random();

    for (int i = 0; i < 10; i++) {
        bool.setSeed(i);
        bool.nextBoolean(); //Only change
        System.out.println(bool.nextBoolean());
    }
}

在我看来,第一次执行时nextBoolean()函数总是返回true,是否有这种现象的原因?

最佳答案

在API中找到setSeed方法的原因:



实际上,您提供的种子值long乘以一个固定值(在Random类中私下定义),然后仅考虑最低有效的48位。即使此乘数很大,由于i值序列都是连续的,因此它们都产生数值上相似的种子值。因此,前几千个值实际上被视为与nextBoolean方法具有相同的值,并且您获得了完全相同的初始 boolean 值。再次调用nextBoolean(而无需再次调用setSeed)将重新乘以种子值,因此您很快就会远离看到相同的模式。

如果您确实调用了setSeed方法,则只需调用一次即可,并且应该在循环之外进行。但是Random类完全可以选择其自己的种子值,因此我建议您完全不要调用setSeed,除非您知道自己为什么这样做。

09-04 02:59