【问题标题】:Java - Generating A Set of Random Numbers Without Duplicates [duplicate]Java - 生成一组没有重复的随机数 [重复]
【发布时间】:2016-03-01 20:26:38
【问题描述】:

使用以下代码,我尝试生成 10 个介于 1 和 50 之间的随机数,而不会打印出任何重复。

我当前的代码在文件 RandomNum.java 中:

public class RandomNum
{
    public static void main(String[] args) 
    {
             int counter = 0;
             int num = 0;
             while(counter<=10)
             {
                    num=(int)(1+Math.random()*(50));
                    System.out.println("The number"+" "+num+" "+"was drawn.");
                    ++counter;
            }
    }
}

此代码成功生成并打印出数字的值,但我想让程序打印出 1 到 50 之间的 10 个唯一数字,而不是包含任何重复的数字。

我该怎么做呢?

谢谢!

【问题讨论】:

    标签: java random while-loop


    【解决方案1】:

    您可以使用随机播放。

    List<Integer> ints = IntStream.range(1, 50).boxed().collect(toList());
    Collections.shuffle(ints);
    List<Integer> ten = ints.subList(0, 10);
    

    或者您可以使用 LinkedHashSet。注意:如果您使用 HashSet,则顺序可能不是很随机。例如如果您以任何顺序将 0 到 10 添加到 HashSet 中,它将恰好按排序顺序。

    Set<Integer> ints = new LinkedHashSet<>();
    Random rand = new Random();
    while(ints.size() < 10)
        ints.add(rand.nextInt(50) + 1);
    // copy to a list to taste.
    

    或者你可以使用地图。

    List<Integer> collect = IntStream.range(1, 50).boxed()
            .collect(groupingBy(i -> Math.random()))
            .values().stream().flatMap(Collection::stream)
            .limit(10).collect(toList());
    

    或者你可以使用 Random.ints

    List<Integer> collect = new Random().ints(1, 50)
            .boxed()
            .collect(Collectors.toCollection(LinkedHashSet::new)) // distinct
            .stream().limit(10)
            .collect(Collectors.toList());
    

    注意:在之前的答案中使用了.distinct(),但是,用于执行唯一性的集合的选择并未定义,事实上在 Java 8 中恰好使用了 HashSet,如前所述,这是一个糟糕的选择。

    【讨论】:

    • 这不会防止重复,对吧?
    • 加一个用于使用 LinkedHashSet 而不是 HashSet。
    • 我不确定我是否喜欢第三种解决方案。它似乎不必要地复杂,它不依赖于groupingBy 的实现细节吗?如果groupingBy 使用LinkedHashMap,它就不是随机的。
    • 嘿...Random.ints() 呢?
    • 我刚刚检查了源代码,IntStream.distinct 是使用LinkedHashSet 完成的。有趣的是,Stream.distinct 的规范指定保持顺序,但IntStream.distinct 不是这样。由于保证了订单的维护,因此无需像 .boxed().distinct() 那样做.boxed().collect(toCollection(LinkedHashSet::new)).stream()
    猜你喜欢
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多