我将实现唯一的随机数生成器。但是在运行它时,它有时会生成与 previous 相同的数字。在这种情况下如何确保生成的数字不重复?
以下是我的代码
int refno = 0;
SecureRandom r = new SecureRandom();
refno = r.nextInt(999999999);
Random
并SecureRandom
返回一个随机数。随机数永远不是唯一的(否则它们不会是随机的)。
要创建唯一标识符,请使用 class java.util.UUID
。
随机数生成器在有限范围内创建数字,因此它迟早必须重复自身。
当您生成的数字范围较小时(例如,当您想模拟一副纸牌时),您可以创建一个包含所有可能值的列表,将其随机洗牌并以现在的随机顺序返回元素。
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
}
}
当由于范围太大而这不可行时,您可以将已经生成的数字存储在一个集合中。在返回结果之前,检查它是否已经在该集合中,如果是,则重新滚动。
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
并在它变得太大时抛出异常。