随机生成java唯一数字

时间:2013-06-24 08:16:23

标签: java random int

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

以下是我的代码

    int refno = 0;

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

3 个答案:

答案 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)

您可以使用UUID

UUID.randomUUID();

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