Every now and then I find myself with indexed loops, for which I want to permutate the order to some random order. I usually transition from something like
for (int i = 0; i < max; i++) {
// do stuff with i
}
to
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
}
This is neither efficient nor elegant. Is it possible to create a Stream
(ideally an IntStream
) in a certain range, but have it return its elements shuffled? I am thinking of something along the lines of:
IntStream.range(0, max)
.shuffled() // this method doesn't exist
.forEach(IntConsumer::accept);
The resulting IntStream
should still include all elements in the range [0, max)
exactly once.
This is not a duplicate of this question, because I don't want to create a List
and shuffle it. This solution has a massive overhead since it is working with Integer
s, while also redundantly creating and shuffling a List
. I have provided that solution in my own example, so I am fully aware of that approach.