Skip to content
Advertisement

Java.util.Collection.Shuffle not producing random results when using a seeded Random

Given the following code:

        List<Integer> consensusGroupOrder = new ArrayList<>();

        for (int i = 0; i < numberOfItems; i++) {
            consensusGroupOrder.add(i + 1);
        }

        Collections.shuffle(consensusGroupOrder, new Random(seed));

        int count = 1;

        Map<Integer, Integer> returnValue = new HashMap<>();

        for(Integer group: consensusGroupOrder) {
            returnValue.put(count++, group);
        }

When I set numberOfItems to 4 and starting with a seed of 1, when dumping returnValue as Json I get:

{
  "1": 4,
  "2": 1,
  "3": 2,
  "4": 3
}

Incrementing seed, the fourth item in the list is always 3. Seed = 5:

{
  "1": 4,
  "2": 1,
  "3": 2,
  "4": 3
}

Seed = 10:

{
  "1": 2,
  "2": 4,
  "3": 1,
  "4": 3
}

Seed = 255:

{
  "1": 1,
  "2": 2,
  "3": 4,
  "4": 3
}

I am seeding Random as I need the result to be deterministic based on seed, but why is the 4th item always 3? Only when seed = 256 does the fourth item change.

I found this question, the answer is to call nextInt() on the Random: Collection.shuffle with seeded Random – anomaly with List of size 16

It feels like calling nextInt() before using the Random is just kicking the problem along the seed value for a while and again it will occur somewhere?

Advertisement

Answer

I just went with the author proposed work-around on Collection.shuffle with seeded Random – anomaly with List of size 16:

        List<Integer> consensusGroupOrder = new ArrayList<>();

        for (int i = 0; i < numberOfItems; i++) {
            consensusGroupOrder.add(i + 1);
        }

        Random r = new Random(seed);
        r.nextInt();

        Collections.shuffle(consensusGroupOrder, r);

        int count = 1;

        Map<Integer, Integer> returnValue = new HashMap<>();

        for(Integer group: consensusGroupOrder) {
            returnValue.put(count++, group);
        }
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement