我期待来自以下Callable
的唯一随机数:
public class UniqueGenerator implements Callable<Integer> {
private static SecureRandom rnd;
static {
try {
rnd = SecureRandom.getInstance("SHA1PRNG");
rnd.setSeed(UUID.randomUUID().toString().getBytes());
} catch (NoSuchAlgorithmException e) {
}
}
@Override
public Integer call() throws Exception {
return rnd.nextInt();
}
}
然而,从1,000,000次执行此方法,我永远不会获得1,000,000个唯一整数。 有什么方法可以得到理想的结果吗? 在尝试生成唯一的整数时我犯了什么错误?
答案 0 :(得分:3)
如果您想要1,000,000个唯一随机整数,请创建一个ArrayList
,其中Integer
个对象从0到999,999,然后使用您的SecureRandom
对象随机播放该列表:
Collections.shuffle(cards, secureRandom);
然后根据需要使用整数,如果列表为空,则重新创建列表。
答案 1 :(得分:1)
当然,他们不会是独一无二的。它们是随机的。对于psuedo随机数生成器来说,吐出与它已经生成的数字相同的数字是非常完美的。如果你运行它足够长,比如2 ^ 32次,你就不会得到2 ^ 32个唯一数字。许多数字将重复出现。如果你想要独特的随机值,UUID是一个好的开始(虽然它们不能保证是唯一的 - 这些都是出于实用目的。)
答案 2 :(得分:1)
如果您想要随机排列的百万个唯一数字,我会使用Collections.shuffle()
。例如,
List<Integer> al = new ArrayList<>();
for (int i = 0; i < 1000 * 1000; i++) {
al.add(i);
}
Collections.shuffle(al);
// al contains 1,000,000 numbers in random order.
答案 3 :(得分:1)
生日悖论。您的整数有4294967296可能的值。为简单起见,让我们说40亿。您正在生成100万随机整数。这意味着这些随机整数中的每一个在4000上大约有1次机会随机地具有与另一个相同的值。那个缝很小,但它是一个整数,你有999999其他情况来测试。这背后的数学有点复杂,但我们只是说重复的几率几乎是1/1。