我目前正在寻找最好的方法,因此在n个int中选择x个唯一的int.它会像Random.nextInt(range)多次一样,但它永远不应该选择两次相同的int.如果它发生x > n那么结果将只包含n个int
我试图自己做这个,我目前基于Fisher/Yates shuffle这样做:
private static final Random R = new Random();
public static int[] distinctRandoms(int nb, int max) {
int[] all = new int[max];
for (int i = 0; i < all.length; i++) {
all[i] = i;
}
if (max <= nb) {
return all;
}
int index;
int[] result = new int[nb];
for (int j = 0, k = all.length - 1; k > 0 && j < nb; k--, j++) {
index = R.nextInt(k + 1);
result[j] = all[index]; // save element
all[index] = all[k]; // overwrite chosen with last element
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
它的工作和性能似乎很好,但我不禁想到仍然必须有一些更高性能的方式这样做,我正在重新发明轮子.我考虑过做不同的事情nb > (max / 2)(删除元素而不是选择元素)但是因为你不能在java中截断数组,你仍然最终会复制你需要的所有元素.如果这种方法花费很多nb = max-1
有没有内置的方法可以在java中有效地随机选择不同的int?
编辑1:
高性能的意思是节省时间.我希望它快.我将主要使用小套的randoms.
编辑2:
我尝试过像这样使用shuffle但是由于所有额外的对象创建,它在时间上要贵得多.
public static Integer[] distinctRandoms2(int nb, int max) {
ArrayList<Integer> all = new ArrayList<Integer>(max);
for (int i = 0; i < max; i++) {
all.add(i);
}
if (max <= nb) {
return all.toArray(new Integer[max]);
}
Collections.shuffle(all);
return all.subList(0, nb).toArray(new Integer[nb]);
}
Run Code Online (Sandbox Code Playgroud)