有时这段代码总是返回相同的数字(有时它可以正常工作):
(new Random()).nextInt(5)
我怀疑问题在哪里 - 它可能总是创建一个具有相同种子的新Random。那么什么是最好的解决方案:
还是其他什么?我不需要任何看似随意的东西。
如果有人可以解释为什么原始代码有时会起作用,有时却没有。
也会有所帮助感谢。
答案 0 :(得分:12)
java.util.Random的javadoc是明确的:
如果创建了两个Random实例 与同一种子,相同 方法调用的序列是为了 每一个,他们都会产生并返回 相同的数字序列。
默认构造函数也很清楚:
创建一个新的随机数生成器。 这个构造函数设置了种子 随机数生成器的值 很可能与任何人截然不同 其他的这个构造函数的调用。
换句话说,没有保证。
如果您需要更随机的算法,请使用java.security.SecureRandom。
答案 1 :(得分:7)
如果你在连续的行上调用那行代码,那么是的,你创建的两个Random实例可以用来自时钟的相同种子创建(时钟毫秒刻度计数是Random对象的默认种子)。几乎普遍,如果应用程序需要多个随机数,您可以创建一个Random实例并根据需要重复使用它。
编辑:有趣的是,javadoc for Random自1.4.2以来发生了变化,这解释了时钟被用作默认种子。显然,这不再是一种保证。
编辑#2:顺便说一下,即使你重复使用正确播种的随机实例,当你调用{{1}时,你仍会得到与前一次调用相同的随机数。 }}
nextInt(5)
答案 2 :(得分:6)
...有时候这段代码[..]会返回相同的数字(有时它可以正常工作)......
所以它随机工作??? :) :) :)
好的,好的,现在就投票给我!
答案 3 :(得分:3)
在Java 1.4中,API文档中指定了新Random
实例的默认种子,它是System.currentTimeMillis()
的结果。显然,紧密循环可以为每个刻度创建许多Random()
个实例,所有实例都具有相同的种子并且都产生相同的伪随机序列。这在某些平台上尤其糟糕,例如Windows,时钟分辨率很差(10毫秒或更高)。
然而,从Java 5开始,每次调用默认构造函数时,种子被设置为“非常可能不同的值”。对于每个Random
实例使用不同的种子,结果应根据需要随机显示。
答案 4 :(得分:1)
Random的Javadoc对此并不明确,但它使用的种子可能取决于当前的系统时间。它确实说明同一种子的随机数是相同的。如果您在相同的毫秒内使用该调用,它将使用相同的种子。最好的解决方案可能是使用静态Random对象并将其用于后续调用方法。
答案 5 :(得分:1)
近似均匀分布的最佳方法是使用静态方法Random.nextInt(n)生成[0,n-1]范围内的整数(是,n不包括在内)。在您的特定示例中,如果您想要0到5(包括0和5)范围内的整数,您可以调用Random.nextInt(6)。