【问题标题】:Random number generator giving inconsistent results随机数生成器给出不一致的结果
【发布时间】:2017-04-12 22:35:15
【问题描述】:

我正在尝试研究如何将 6 个随机生成的数字添加到 HashSet。我得到了结果,但它们不一致。有时它会在控制台上打印 6 个数字,有时它会在控制台上打印 5 个数字。

我今天早上才开始接触这些东西,所以如果它太明显了,我深表歉意,并感谢您的帮助。

 HashSet<Integer> generatedLotteryNumbers = new HashSet<Integer>();
Random r = new Random();

for(int i=0; i<6; i++){
  generatedLotteryNumbers.add(r.nextInt(49));
}

System.out.println(generatedLotteryNumbers);

【问题讨论】:

  • 只要研究一下Java Sets的特性,你就会知道这里发生了什么。
  • 喜欢这个标题。
  • 是的,我不知道该怎么说,shmosel
  • 顺便说一下,在 Java 中,变量的命名应该以小写字母开头。所以使用generatedLotteryNumbers

标签: java random hashset


【解决方案1】:

这是因为GeneratedLotteryNumbers 是一个HashSet(它的作用类似于一个集合),而java 中的HashSet 不会插入其中已经存在的项目,因此不允许重复,所以如果你得到的元素少于 6 个,这是因为有些元素很常见,因此只存储一次。

最好试试这个:

ArrayList<Integer> GeneratedLotteryNumbers = new ArrayList<Integer>();
Random r = new Random();
for(int i=0; i<6; i++){
    GeneratedLotteryNumbers.add(r.nextInt(49));
}

要检测重复插入,捕获Set::add方法返回的booleanTRUE添加成功,如果重复则FALSE

【讨论】:

  • 对了。我知道它只存储了一次值,但我没有意识到它只是省略了重复项。谢谢。
  • Hashset 不允许插入重复项,有关详细信息,请参阅:stackoverflow.com/questions/12940663/…,如果解决了您的问题,请将答案标记为已接受。 :) @Schming
  • @Schming 它会省略重复的,但add 方法会在发生这种情况时返回false。所以它不是完全无声的。
  • 您最好保持adding 直到大小达到您的目标。您实现的计数循环并不能解决 OP 的问题。
【解决方案2】:

Set 不能包含重复值,因此如果生成器两次生成相同的数字,它将被删除。相反,您应该根据Set 的大小循环(或使用List):

while (generatedLotteryNumbers.size() < 6) {
    generatedLotteryNumbers.add(r.nextInt(49));
}

如果您使用的是 Java 8,另一种选择是使用 Random#ints 生成一个 Stream,您可以使用它直接创建您的 Set

Set<Integer> generatedLotteryNumbers = r.ints(0, 49)
                                        .distinct()
                                        .limit(6)
                                        .boxed()
                                        .collect(Collectors.toSet());

【讨论】:

  • 有趣。我没有意识到你可以在无限流上调用distinct()
  • 这个答案的一个小问题是它理论上可以无限运行,并且随着目标大小 (6) 接近最大值 (49),性能可能会下降。我认为更正确的方法是打乱所有潜在值的数组并选择前 n 个元素。
  • @schmosel 好吧,如果我们是理论上的,那么每次迭代循环无限运行的概率都会收敛到 0。所以理论上,循环无限的可能性为 0%。您能解释一下性能问题的含义吗?
  • 用 1,000,000 的范围和 100,000 的限制对您的代码进行基准测试。现在将限制更改为 900,000,这将花费更长的时间。
  • @shmosel 啊,我明白了。那么,在这种情况下,另一种选择是从列表中删除一个随机项目,直到它达到所需的长度。我认为最好的算法取决于范围内所需集合的密度。我很想知道哪种算法适合每种密度。
猜你喜欢
  • 2011-09-18
  • 1970-01-01
  • 2015-02-16
  • 2022-06-17
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 2023-01-03
  • 1970-01-01
相关资源
最近更新 更多