Java
random permutation
algorithms
collections
programming techniques

How to generate a random permutation in Java

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

A random permutation is a shuffled ordering of a set of values where every element appears exactly once. In Java, the most practical way to generate one is to start with a collection and shuffle it using a proper random source. The important part is to use an algorithm that gives each ordering a fair chance rather than piecing together random swaps incorrectly.

The Simplest Approach: Collections.shuffle

For most applications, Collections.shuffle is the right answer. It applies a Fisher-Yates style shuffle to a list, which is the standard algorithm for producing an unbiased random permutation.

java
1import java.util.ArrayList;
2import java.util.Collections;
3import java.util.List;
4
5public class ShuffleExample {
6    public static void main(String[] args) {
7        List<Integer> values = new ArrayList<>();
8        for (int i = 1; i <= 10; i++) {
9            values.add(i);
10        }
11
12        Collections.shuffle(values);
13        System.out.println(values);
14    }
15}

If you run this program multiple times, the list order changes while still containing every number from 1 to 10 exactly once.

Reproducible Shuffles

Sometimes you want the shuffle to be random but repeatable, especially in tests or simulations. In that case, pass your own Random instance with a fixed seed.

java
1import java.util.ArrayList;
2import java.util.Collections;
3import java.util.List;
4import java.util.Random;
5
6public class SeededShuffle {
7    public static void main(String[] args) {
8        List<String> names = new ArrayList<>(List.of("Ava", "Ben", "Cara", "Dylan"));
9        Random random = new Random(42);
10
11        Collections.shuffle(names, random);
12        System.out.println(names);
13    }
14}

Using the same seed produces the same permutation, which is often exactly what you want in automated tests.

Building a Permutation of Indexes

A common variant is to generate a random permutation of indexes rather than shuffle the data directly. This is useful when you want to traverse another structure in random order without modifying the original data.

java
1import java.util.ArrayList;
2import java.util.Collections;
3import java.util.List;
4
5public class IndexPermutation {
6    public static List<Integer> randomPermutation(int n) {
7        List<Integer> indexes = new ArrayList<>();
8        for (int i = 0; i < n; i++) {
9            indexes.add(i);
10        }
11        Collections.shuffle(indexes);
12        return indexes;
13    }
14
15    public static void main(String[] args) {
16        System.out.println(randomPermutation(6));
17    }
18}

This is a clean pattern for sampling, randomized test ordering, and randomized processing pipelines.

Manual Fisher-Yates for Arrays

If you are working with primitive arrays and want to avoid boxing into a List<Integer>, implement the Fisher-Yates shuffle directly.

java
1import java.util.Arrays;
2import java.util.Random;
3
4public class FisherYatesArray {
5    public static void shuffle(int[] values, Random random) {
6        for (int i = values.length - 1; i > 0; i--) {
7            int j = random.nextInt(i + 1);
8            int temp = values[i];
9            values[i] = values[j];
10            values[j] = temp;
11        }
12    }
13
14    public static void main(String[] args) {
15        int[] values = {1, 2, 3, 4, 5, 6};
16        shuffle(values, new Random());
17        System.out.println(Arrays.toString(values));
18    }
19}

The loop goes backward, selecting a random index from the unshuffled prefix each time. That detail is what makes Fisher-Yates unbiased.

When to Use SecureRandom

If the permutation affects security-sensitive behavior such as token generation, lotteries with adversarial stakes, or security tests, use SecureRandom instead of Random.

java
1import java.security.SecureRandom;
2import java.util.ArrayList;
3import java.util.Collections;
4import java.util.List;
5
6SecureRandom secureRandom = new SecureRandom();
7List<Integer> values = new ArrayList<>(List.of(1, 2, 3, 4, 5));
8Collections.shuffle(values, secureRandom);

For ordinary application logic, Random is usually fine. For security-sensitive randomness, it is not.

Common Pitfalls

A common mistake is repeatedly picking random elements and retrying duplicates until the list is full. That works, but it is less efficient and easier to get wrong than shuffling once.

Another mistake is writing a custom swap loop that uses the wrong range for the random index. If you always pick from the full array instead of the shrinking unshuffled portion, the permutation can be biased.

Developers also sometimes forget whether they need reproducibility. Tests often benefit from a fixed seed, while production behavior usually should not.

Finally, do not use Random when the shuffle affects security-sensitive outcomes. Use SecureRandom for that case.

Summary

  • 'Collections.shuffle is the easiest way to generate a random permutation in Java.'
  • It is based on the Fisher-Yates shuffle, which is the standard unbiased approach.
  • Pass a seeded Random when you need reproducible results.
  • Implement Fisher-Yates directly for primitive arrays if needed.
  • Use SecureRandom when the randomness has security implications.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.