在Java中,实现不重复的随机数生成是一个常见的需求,特别是在需要生成不重复元素集合的场合,如洗牌算法、抽奖系统等。下面我将详细介绍几种实现方法。
1. 使用Set集合
一种简单直接的方法是使用Set集合来存储已经生成的随机数,以确保不会重复。Set集合在Java中不允许有重复的元素。
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class UniqueRandomNumberGenerator {
private Set<Integer> numbers = new HashSet<>();
private Random random = new Random();
public int generateUniqueRandom(int max) {
int randomNumber;
do {
randomNumber = random.nextInt(max + 1);
} while (numbers.contains(randomNumber));
numbers.add(randomNumber);
return randomNumber;
}
public static void main(String[] args) {
UniqueRandomNumberGenerator generator = new UniqueRandomNumberGenerator();
for (int i = 0; i < 10; i++) {
System.out.println(generator.generateUniqueRandom(100));
}
}
}
在上面的代码中,generateUniqueRandom方法会一直生成随机数,直到生成一个不在Set中的随机数。这种方法简单,但是当需要生成的随机数接近max值时,效率会降低。
2. 使用Fisher-Yates洗牌算法
Fisher-Yates洗牌算法(也称为Knuth洗牌)是一种高效的随机排列算法。我们可以通过这种方法来生成不重复的随机数序列。
import java.util.Random;
public class FisherYatesShuffle {
private Random random = new Random();
public int[] generateUniqueRandomArray(int n) {
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
for (int i = array.length - 1; i > 0; i--) {
int index = random.nextInt(i + 1);
// Simple swap
int a = array[index];
array[index] = array[i];
array[i] = a;
}
return array;
}
public static void main(String[] args) {
FisherYatesShuffle shuffle = new FisherYatesShuffle();
int[] randomNumbers = shuffle.generateUniqueRandomArray(10);
for (int number : randomNumbers) {
System.out.println(number);
}
}
}
这个方法的时间复杂度是O(n),适用于需要生成一系列不重复随机数的情况。
3. 使用Java 8的流(Stream)
Java 8引入了流(Stream)的概念,我们可以使用流来生成不重复的随机数。
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class StreamUniqueRandomNumberGenerator {
private Random random = new Random();
public List<Integer> generateUniqueRandomList(int n) {
return IntStream.rangeClosed(1, n)
.boxed()
.collect(Collectors.collectingAndThen(Collectors.toList(), list -> {
for (int i = list.size() - 1; i > 0; i--) {
int index = random.nextInt(i + 1);
int a = list.get(index);
list.set(index, list.get(i));
list.set(i, a);
}
return list;
}));
}
public static void main(String[] args) {
StreamUniqueRandomNumberGenerator generator = new StreamUniqueRandomNumberGenerator();
List<Integer> randomNumbers = generator.generateUniqueRandomList(10);
randomNumbers.forEach(System.out::println);
}
}
这个方法利用了Java 8的流操作,使得代码更加简洁。
以上是几种在Java中实现不重复随机数生成的方法。每种方法都有其适用的场景和优缺点,你可以根据实际需求选择合适的方法。
