Is Collections.shuffle() really random enough? Practical examples seem to deny this statement Is Collections.shuffle() really random enough? Practical examples seem to deny this statement arrays arrays

Is Collections.shuffle() really random enough? Practical examples seem to deny this statement


Its human nature to see patterns which are not there. Many people see patterns in the planets and stars as guiding their life.

In the first 1000 digits of PI there are six nines in a row. Does that mean the digits of PI are not random? no. The pattern doesn't occur again any more than your might expect.

Having said that, Random is not completely random and it will repeat after 2^48 calls. (it uses a 48-bit seed) This means its not possible to produce every possible long or double using it. If you want more randomness you can use SecureRandom with shuffle instead.

It sounds like what you want is something like this

List<String> imagePaths = new ArrayList<>();// called repeatedlyif (imagePaths.size() <= 500) {    imagePaths = get1000Images();    Collections.shuffle(imagePaths);}for (String path: imagePaths.subList(0, 20)) {  ... do something with the path ...}imagePaths = imagePaths.subList(20, imagePaths.size());

This will ensure that you don't see the same image in the last 500 calls.


If you're showing 20 images out of 1000 the probability of seeing any one of that 20 repeated in the next iteration is approximately 0.34 so you shouldn't be surprised to see images repeating.

The chances of seeing a specific image is still one in a thousand, but if you're looking for twenty images the chances are much higher.

We can calculate the probability of none of the previous 20 images repeating as:

 980   979         961———— × ——— × ... × ——— ≈ 0.661000   999         981

And so the probability of seeing a repeat is one minus this, or approximately 0.34.

And the probability of seeing an image repeated in either of the next two iterations is:

1 - (0.66 × 0.66) ≈ 0.56

In other words, it's more likely than not that you'll see a repeated image over the two following cycles. (And this isn't including images repeated from the second cycle in the third which will only make it more likely.)

For what it's worth, here's some Java code to do the above calculation:

float result = 1.0f;int totalImages = 1000;int displayedImages = 20;for (int i = 0; i < displayedImages; i++) {  result = result * (totalImages - displayedImages - i) / (totalImages - i);}System.out.println(result);


Your intuition is correct for a specific image [you are not likely to see a specific image over and over again], but not for a general image [you are likely to see some image repeating]. This is one of these places in probability that our automatic intuition is wrong...

This reminds me the birthday paradox, which contradicts the intuition, and says - for a group of 23 people, the likelihood of 2 of them having the same birthday is 0.5, much more then the intuition expects!