我将实现唯一的随机数生成器。但是在运行时,它有时会生成与之前相同的数字。在这种情况下如何确保生成的数字不重复?
以下是我的代码
int refno = 0;
SecureRandom r = new SecureRandom();
refno = r.nextInt(999999999);
答案 0 :(得分:8)
Random
以及SecureRandom
也会返回一个随机数。随机数永远不会是唯一的(否则它们不是随机的)。
要创建唯一标识符,请使用班级java.util.UUID
。
答案 1 :(得分:2)
随机数生成器在有限范围内创建数字,因此它必须迟早重复。
当您生成的数字范围很小时(例如,当您想要模拟一副牌时),您可以创建一个包含所有可能值的列表,随机随机播放并按现在随机顺序返回元素。
class UniqueRandom {
private LinkedList<Integer> results;
public UniqueRandom(int range) {
results = new LinkedList<Integer>(range);
for (var i = 0; i < range; i++) {
results.add(i);
}
Collection.shuffle(results, new SecureRandom());
}
public int nextInt() throws NoSuchElementException {
return results.pop(); // will throw NoSuchElementException when all values are used up
}
}
当由于范围太大而无法执行此操作时,您可以存储已在Set中生成的数字。在返回结果之前,请检查它是否已经存在于该集合中,如果已经存在,请重新注册。
class UniqueRandom {
private Set<Integer> used = new HashSet<Integer>();
private Random rand = new SecureRandom();
public int nextInt(int max) {
Integer ret = null;
do {
ret = rand.nextInt(max);
} while (used.add(ret) == false);
return ret;
}
}
警告:后面的算法会越慢越慢,你生成的数字越多,并且当所有值都用完后最终会进入无限循环,所以只有在你可以确定结果范围永远不会耗尽。或者,您可以检查used
的大小,并在它变得太大时抛出异常。
答案 2 :(得分:1)