我时不时地发现自己处于索引循环中,为此,我想将其顺序排列为一些随机顺序。 我通常会从类似
的地方过渡for (int i = 0; i < max; i++) {
// do stuff with i
}
到
List<Integer> indices = IntStream.range(0, max)
.boxed()
toCollection(() -> new ArrayList(max)));
Collections.shuffle(indices);
for (int i = 0; i < max; i++) {
int index = indices.get(i);
// do stuff with index
}
这既不高效也不优雅。是否可以在一定范围内创建Stream
(理想情况下为IntStream
),但是否让其元素改组?我在想一些类似的事情:
IntStream.range(0, max)
.shuffled() // this method doesn't exist
.forEach(IntConsumer::accept);
生成的IntStream
仍应一次准确地包含[0, max)
范围内的所有元素。
这不是this question的副本,因为我不想创建List
并对其进行洗牌。由于该解决方案可与Integer
一起使用,因此会产生大量开销,同时还会冗余地创建和改组List
。我已经在自己的示例中提供了该解决方案,因此我完全了解该方法。
答案 0 :(得分:5)
这个怎么样?您几乎拥有了同样的东西,除了它封装了所有的坚韧不拔的东西,只为您提供了一个纯IntStream
。另外,它也不必进行太多装箱和拆箱操作。
public class ShuffledIntStream {
public static IntStream to(int max) {
Random r = new Random();
int[] values = new int[max];
for (int i = 0; i < max; i++) {
values[i] = i;
}
for (int i = max; i > 1; i--) {
swap(values, i - 1, r.nextInt(max));
}
return IntStream.of(values);
}
private static void swap(int[] values, int i, int j) {
int temp = values[i];
values[i] = values[j];
values[j] = temp;
}
}
答案 1 :(得分:1)
您可以使用Random.ints
:
new Random().ints(0, max)
.distinct()
.limit(max)
.forEach(IntConsumer::accept);