在Java中生成唯一的随机数

Öme*_* AK 73 java random

我试图获得0到100之间的随机数.但是我希望它们是唯一的,而不是在序列中重复.例如,如果我得到5个数字,它们应该是82,12,53,64,32而不是82,12,53,12,32我使用它,但它在序列中生成相同的数字.

Random rand = new Random();
selected = rand.nextInt(100);
Run Code Online (Sandbox Code Playgroud)

And*_*son 127

  • 列表结构中按顺序添加范围中的每个数字.
  • 洗牌吧.
  • 拿第一个'n'.

这是一个简单的实现.这将打印1-10范围内的3个唯一随机数.

import java.util.ArrayList;
import java.util.Collections;

public class UniqueRandomNumbers {

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i=1; i<11; i++) {
            list.add(new Integer(i));
        }
        Collections.shuffle(list);
        for (int i=0; i<3; i++) {
            System.out.println(list.get(i));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如Mark Byers在现在删除的答案中所指出的那样,原始方法修复的第一部分是仅使用单个Random实例.

这就是导致数字相同的原因.一个Random实例是由以毫秒为单位的当前时间播种.对于特定的种子值, "随机"实例将返回完全相同伪随机数序列.

  • 您不必洗牌整个范围。如果您想要 n 个唯一的数字,则只需使用 Fisher-Yates 洗牌对前 n 个位置进行洗牌即可。这可能有助于处理较大的列表和较小的 n。 (4认同)
  • +1用于指出单个随机实例*和*回答问题.:) (3认同)

Ale*_*lex 45

利用Java 8+可以使用ints的方法Random来获得一个IntStream随机值,然后distinctlimit到流减少了许多独特的随机值.

ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

Random如果你需要那些,还有创建LongStreams和DoubleStreams的方法.

如果您希望以随机顺序在一个范围内的所有(或大量)数字,将所有数字添加到列表中更有效,将其洗牌并取第一个n,因为上面的示例当前已实现通过在所请求的范围内生成随机数并将它们传递给集合(类似于Rob Kielty的答案),这可能需要生成比传递到限制的数量多得多的数量,因为生成新唯一数字的概率随着每个发现的数量而减少.以下是另一种方式的示例:

List<Integer> range = IntStream.range(0, 100).boxed()
        .collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)


Hot*_*cks 18

  1. 创建一个包含100个数字的数组,然后随机化它们的顺序.
  2. 设计范围为100的伪随机数生成器.
  3. 创建一个包含100个元素的布尔数组,然后在选择该数字时将元素设置为true.当您对数组选择下一个数字检查时,如果设置了数组元素,请再次尝试.(您可以创建一个易于清除的布尔数组,long其中包含移位和掩码的数组,以访问各个位.)

  • +1为替代方法;[`pick()`](http://stackoverflow.com/questions/2523492/choosing-random-numbers-effectively/2524394#2524394)是一个示例。 (2认同)

tra*_*god 16

使用Collections.shuffle()上的所有100个号码,然后选择第5名,如图所示这里.


Ken*_*son 12

我觉得这种方法值得一提.

   private static final Random RANDOM = new Random();    
   /**
     * Pick n numbers between 0 (inclusive) and k (inclusive)
     * While there are very deterministic ways to do this,
     * for large k and small n, this could be easier than creating
     * an large array and sorting, i.e. k = 10,000
     */
    public Set<Integer> pickRandom(int n, int k) {
        final Set<Integer> picked = new HashSet<>();
        while (picked.size() < n) {
            picked.add(RANDOM.nextInt(k + 1));
        }
        return picked;
    }
Run Code Online (Sandbox Code Playgroud)


Rob*_*lty 8

我重新考虑了Anand的答案,不仅要使用Set的唯一属性,还要使用set.add()当set添加失败时返回的boolean false .

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class randomUniqueNumberGenerator {

    public static final int SET_SIZE_REQUIRED = 10;
    public static final int NUMBER_RANGE = 100;

    public static void main(String[] args) {
        Random random = new Random();

        Set set = new HashSet<Integer>(SET_SIZE_REQUIRED);

        while(set.size()< SET_SIZE_REQUIRED) {
            while (set.add(random.nextInt(NUMBER_RANGE)) != true)
                ;
        }
        assert set.size() == SET_SIZE_REQUIRED;
        System.out.println(set);
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 6

我这样做了.

    Random random = new Random();
    ArrayList<Integer> arrayList = new ArrayList<Integer>();

    while (arrayList.size() < 6) { // how many numbers u need - it will 6
        int a = random.nextInt(49)+1; // this will give numbers between 1 and 50.

        if (!arrayList.contains(a)) {
            arrayList.add(a);
        }
    }
Run Code Online (Sandbox Code Playgroud)