关于Java:为什么使用带有硬编码种子的Random会产生相同的结果?

Why does the use of Random with a hardcoded seed always produce the same results?

本问题已经有最佳答案,请猛点这里访问。

Java中的以下简单程序使用EDCOX1×0类,这样它总是显示"hello World"。代码段如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package nomain;

import java.util.Random;

final public class J
{
    public static String randomString(int seed)
    {
        Random rand = new Random(seed);
        StringBuilder sb = new StringBuilder();

        for(int i=0;;i++)
        {
            int n=rand.nextInt(27);
            if (n==0)
            {
                break;
            }
            sb.append((char) ('`'+n));
        }
        return sb.toString();
    }

    public static void main(String args[])
    {
        System.out.println(randomString(-229985452)+' '+randomString(-147909649));
    }
}

令人惊讶的是,它总是显示"hello world",即使使用了导致随机数生成的随机类,每次运行时都应更改数字,相应的字符也应相应更改,但它始终只显示一个稳定的字符串,如上文所述"hello world"。为什么会这样?


答案是正在传入的参数。这是用来给随机数生成器种子的。

1
Random rand = new Random(seed);

prng并不是真正随机的-它们是确定性的,但被设计来模拟随机性。因此,它们被更好地称为"伪随机数生成器"。

对于给定的种子,prng将始终生成相同的数字。然后,它很可能使用其最后一个结果作为下一个值的输入,因此通过使用已知值播种prng,您将始终生成一个已知的"随机"数字序列。

这些数字-229985452和-147909649是已知的种子,这将导致特定的prng产生一个由5个数字组成的序列,可以解释为"hello"和"world"。如果要更改这些数字,您将得到不同的5个字符序列,但只要种子保持不变,它们对于程序的每次运行都是相同的。