我发现这种方法似乎在你给它2的幂时失败了很难.鉴于两个不同种子的随机对象,它们似乎是当被要求返回0(包括)和之间的整数时返回的第一个整数两个(独占)的力量总是一样的; 种子没关系.例如:
public static void main(String[] args) {
Random mRandom;
for (int i = 0; i < 10; i++) {
mRandom = new Random(i);
System.out.println(mRandom.nextInt((int) Math.pow(2, 4)));
}
}
Console:
11
11
11
11
11
11
11
11
11
11
Run Code Online (Sandbox Code Playgroud)
我任意选择2 ^ 4,但它似乎适用于任何2的幂.这是怎么回事?此外,我该如何避免这种情况?
出现此问题的原因有两个.
Random上课同样的种子.nextInt(int n),如果n是2的幂因为,您已Random使用新seed值启动了新实例,这会对nextInt值生成产生影响.根据爪哇的Java文档(长种子).
使用单个长种子创建新的随机数生成器.种子是伪随机数生成器的内部状态的初始值,它由方法next(int)维护.
Run Code Online (Sandbox Code Playgroud)The invocation new Random(seed) is equivalent to: Random rnd = new Random(); rnd.setSeed(seed);
如果你尝试生成随机值new seed,即使是新的Random类实例,也不会产生真正的随机值.
for (int i = 0; i < 10; i++) {
mRandom = new Random(); // Without seed
System.out.println(mRandom.nextInt((int) Math.pow(2, 4)));
}
Run Code Online (Sandbox Code Playgroud)
输出: 2 1 12 4 3 9 9 8 2 9
除此之外,Random#nextInt具有2的幂的效果.如果n是2的幂,它将返回(int)((n * (long)next(31)) >> 31),对于相同的n,它将总是相同.根据nextInt算法,
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
return val;
}
Run Code Online (Sandbox Code Playgroud)