生成随机数,但必须使用不重复的唯一数字生成

Generating random Numbers , but it must be Generated with Unique numbers without replications

int[] drawNumbers = new int[10];//Array With 10 Random Numbers USED for DRAWN NUMBERS
String x = "Drawn Numbers: ";
List<Ticket> ticketWon ;

do{
    //GENERATING 10 Random Numbers
    for (int i = 0; i <= drawNumbers.length -1 ; i++) {
           Random r = new Random();
           drawNumbers[i] = r.nextInt(99) + 1;
           x += drawNumbers[i] + " ";
    }
}

我正在尝试生成 10 个必须随机生成且唯一的随机数。我的问题是 Random r = new Random() 有时会显示重复的数字。如何在不重复的情况下生成 1 到 99 范围内的 10 个随机数?

彩票系统有问题

我想使用 Collection.Shuffle 但我不确定应该如何实施。

使用 list 会更容易,因此您可以检查它是否已经包含号码,如果包含则重新生成。

List<Integer> drawNumbers = new ArrayList<Integer>();
Random r = new Random();
int newNumber = -1;
do
{
    newNumber = r.nextInt(99) + 1;
} while(drawNumbers.contains(newNumber); //Make sure the number is not already in the list.

然后将其放入循环中重复 10 次。

我会生成随机数并将它们保存到 Set,直到我得到 10 个数字。然后从中创建一个列表,将其打乱,然后从中取出数字。

final int NUMBERS_TO_DRAW = 10;
Random r = new Random();

// Generate NUMBERS_TO_DRAW random numbers 
Set<Integer> randoms = new HashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
    randoms.add(r.nextInt(99) + 1);
}

// Now shuffle them:
List<Integer> shuffledRandom = new ArrayList<>(randoms);
Collections.shuffle(shuffledRandom);

编辑:
正如@MarkPeters 在评论中指出的那样,使用 LinkedHashSet 将消除洗牌的需要:

final int NUMBERS_TO_DRAW = 10;
Random r = new Random();

// Generate NUMBERS_TO_DRAW random numbers 
LinkedHashSet<Integer> randoms = new LinkedHashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
    randoms.add(r.nextInt(99) + 1);
}

您可以大致将此问题想象成有一副编号为 1 到 99 的纸牌,并且您想从中挑选 10 张。解决方案是以编程方式创建该套牌,然后从该套牌中随机 select 并从该套牌中移除。

我们可以将一副牌建模为一个整数列表,并用从 1 到 99 的条目填充该列表,如下所示:

List<Integer> deck = new ArrayList<Integer>();
for( int i=1; i<=99; i++ ){
  deck.add( i );
}

然后我们需要在第 0 张卡片(列表从 0 开始编号)和列表中的元素数量之间随机选择一张卡片:

int draw = r.nextRandom( deck.size() );
Integer card = deck.remove( draw );

并重复 10 次,用 "card" 做一些事情(比如,将它放入一个数组,或另一个列表,或其他任何东西:

int drawNumbers = new int[10];
for( int co=0; co<10; co++ ){
  int draw = r.nextRandom( deck.size() );
  Integer card = deck.remove( draw );
  drawNumbers[co] = card;
}

使用Set<Integer>.

Set<Integer> set = new HashSet<Integer>();
int[] drawNumbers = new int[10];
Random r = new Random();
for(int i=0; i<10; i++)
{
    drawNumbers[i] = r.nextInt(99) + 1;
    while(set.contains(drawNumbers[i]))
        drawNumbers[i] = r.nextInt(99) + 1;
    set.add(drawNumbers[i]);
}

这是实现您想要的结果的另一种方法。我们用值 1 到 99 填充一个列表。然后我们打乱列表并获取前 10 个值:

public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    for (int i=1; i<100; i++) {
        list.add(new Integer(i));
    }
    Collections.shuffle(list);
    for (int i=0; i<10; i++) {
        System.out.println(list.get(i));
    }
}

您不必 import/directly 处理 Random,这是一个优点。但是,正如@Voicu(在评论中)指出的那样, shuffle 确实利用了 random:

public static void shuffle(List<?> list) {
    if (r == null) { 
        r = new Random();
    }
    shuffle(list, r);
}
private static Random r;