我有一个生成随机数的方法,但我希望其中一些被丢弃。 这是代码:
public static int getRandomX(int max, int[] exclude){
Random randomGenerator = new Random();
Integer[] toExclude = Arrays.stream( exclude ).boxed().toArray(Integer[]::new);
Integer random = Integer.valueOf(randomGenerator.nextInt(max));
do{
System.out.println(!Arrays.asList(toExclude).contains(random));
if(!(Arrays.asList(toExclude).contains(random))){
return random;
} else{
random ++;
}
}while(!Arrays.asList(toExclude).contains(random));
return random;
}
即使System.out.println(!Arrays.asList(toExclude).contains(random));
打印错误,如果执行,我得到的也是错误的随机数
答案 0 :(得分:2)
while循环中逻辑不正确。您需要执行循环,只要有一个需要排除的数字即可,而不是相反。
只需将代码用于:
public static int getRandomX(int max, int[] exclude) {
Random randomGenerator = new Random();
Integer[] toExclude = Arrays.stream(exclude).boxed().toArray(Integer[]::new);
Integer random;
do {
random = Integer.valueOf(randomGenerator.nextInt(max));
} while (Arrays.asList(toExclude).contains(random));
return random;
}
答案 1 :(得分:1)
我更喜欢使用集合而不是列表。好处是您可以向集合中添加元素,并根据元素是否存在set.add
返回true或false,使while循环更容易且更具可读性:
public static int getRandomX(int max, int[] exclude){
Set<Integer> set = Arrays.stream(exclude).boxed().collect(Collectors.toSet());
Random randomGenerator = new Random(max);
Integer random = randomGenerator.nextInt(max);
while(!set.add(random)){
random = randomGenerator.nextInt(max);
}
return random;
}
但是要小心!如果exclude包含0到max-1之间的所有数字,则此方法和@Nicholas K
的方法都将以一个无限循环结束。为防止这种情况,请添加以下参数的验证。与列表相比,集还有另一个优点,因为您不必先过滤重复项。
public static int getRandomX(int max, int[] exclude){
Set<Integer> set = Arrays.stream(exclude).boxed().collect(Collectors.toSet());
if(set.size() == max){
throw new IllegalArgumentException("All numbers in range [0 - " +(max-1)+"] excluded");
//or return -1;
}
Random randomGenerator = new Random(max);
Integer random = randomGenerator.nextInt(max);
while(!set.add(random)){
random = randomGenerator.nextInt(max);
}
return random;
}