0

我将实现唯一的随机数生成器。但是在运行它时,它有时会生成与 previous 相同的数字。在这种情况下如何确保生成的数字不重复?

以下是我的代码

    int refno = 0;

    SecureRandom r = new SecureRandom();
    refno = r.nextInt(999999999);
4

3 回答 3

8

RandomSecureRandom返回一个随机数。随机数永远不是唯一的(否则它们不会是随机的)。

要创建唯一标识符,请使用 class java.util.UUID

于 2013-06-24T08:20:52.207 回答
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
      }
 }

当由于范围太大而这不可行时,您可以将已经生成的数字存储在一个集合中。在返回结果之前,检查它是否已经在该集合中,如果是,则重新滚动。

 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并在它变得太大时抛出异常。

于 2013-06-24T08:23:45.237 回答
1

您可以使用UUID

UUID.randomUUID();

由于 UUID 是 128 位数字,因此您必须将其转换为 BigInteger。

于 2013-06-24T08:25:46.637 回答