随机发生器每次给我相同的数字

import java.util.Random; public class Fighter { int str; int dex; int hth; Random gen = new Random(1535636); public Fighter() { str = gen.nextInt(9); dex = gen.nextInt(9); hth = gen.nextInt(14); } public int getHth(){ return hth; } public int getStr(){ return str; } public int getDex(){ return dex; } } import java.util.Random; public class Arena { public static void main(String[] args) { Random gen = new Random(); Fighter Guy1 = new Fighter(); int x =1; while (x < 200000000){ x++; } Fighter Guy2 = new Fighter(); int hth1 = Guy1.getHth(); int hth2 = Guy2.getHth(); System.out.println("Fight Start"); System.out.println("---------------"); //System.out.println(gen.nextInt(10)); //System.out.println(gen.nextInt(17)); System.out.println(Guy1.getStr()); //Fighting } } 

无论什么时候我运行这个,我得到相同的结果,无论如何。 我希望每次都能制作2个随机战士。 现在有几行只是为了确认它不会产生随机数。

有谁知道如何在构造函数中正确使用随机数? 或者我这样做完全错了?

您为随机数生成器提供了一个常量种子值:

 Random gen = new Random(1535636); 

不要那样做。 它将始终提供相同的值。 只需调用默认构造函数:

 Random gen = new Random(); 

创建一个新的随机数生成器。 其种子初始化为基于当前时间的值:

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#Random()


为什么?

与大多数“标准库”随机数生成器一样, Random是“伪随机数生成器” 。 这意味着它实际上并没有生成随机数! 相反,它是以非常明确的方式计算它们 – 它们看起来像随机数,并且它们往往具有良好的分布。

使用种子值初始化PRNG,该种子值设置其内部状态。 如果每次都提供相同的种子值,PRNG每次运行时都将处于相同的状态,从而提供相同的数字序列!

使它们看起来随机的东西,通常是1默认情况下它们是“播种”的,具有基于时间的值。 在大多数库中,这是一个具有非常精确的时间值。 所以大多数时候,如果你看到有人播种他们的PRNG,那可能是不正确的,或者至少是非常不必要的。

1 – 注意:来自libc的rand() 不是这种情况: “如果没有提供种子值,则rand()函数会自动播种,值为1。”

现在,您正在使用相同的种子初始化随机数生成器。 这将使它每次都产生相同的数字序列。 您想要使用no-arg构造函数 :

 Random gen = new Random(); 

根据文件

此构造函数将随机数生成器的种子设置为非常可能与此构造函数的任何其他调用不同的值。