ZetCode

Java Collections.shuffle Method

Last modified: April 20, 2025

The Collections.shuffle method is part of Java's Collections Framework. It randomly permutes the specified list using a default or specified source of randomness. This method is useful for randomization tasks in Java.

Shuffling is commonly needed in applications like games, simulations, and statistical sampling. The method operates in linear time and modifies the original list rather than returning a new shuffled list.

Collections.shuffle Overview

The Collections.shuffle method has two overloaded versions. One takes just a List, using a default random source. The other takes both a List and a Random object for controlled randomness. Both versions shuffle in-place.

The method uses the Fisher-Yates shuffle algorithm internally. This algorithm produces a uniformly random permutation of the list elements. The time complexity is O(n) where n is the list size.

Basic Shuffle Example

This example demonstrates the simplest use of Collections.shuffle. We create a list of numbers and shuffle them. The output shows the list before and after shuffling.

BasicShuffle.java
package com.zetcode;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class BasicShuffle {

    public static void main(String[] args) {
        
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        
        System.out.println("Original list: " + numbers);
        
        Collections.shuffle(numbers);
        
        System.out.println("Shuffled list: " + numbers);
    }
}

This code creates an immutable list of numbers using Arrays.asList. We print the original order, then call Collections.shuffle to randomize the list. Finally, we print the shuffled result.

Each run produces different output because the shuffle is random. The original list remains unchanged if you need to preserve it, create a copy first.

Shuffling with Custom Random Source

This example shows how to use a specific Random object with Collections.shuffle. Using a seeded Random allows reproducible shuffles, which is useful for testing and debugging.

SeededShuffle.java
package com.zetcode;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class SeededShuffle {

    public static void main(String[] args) {
        
        List<String> colors = Arrays.asList("Red", "Green", "Blue", "Yellow");
        Random random = new Random(42); // Fixed seed for reproducibility
        
        System.out.println("Original: " + colors);
        
        Collections.shuffle(colors, random);
        System.out.println("First shuffle: " + colors);
        
        // Reshuffle with same seed
        random.setSeed(42);
        Collections.shuffle(colors, random);
        System.out.println("Second shuffle: " + colors);
    }
}

We create a list of colors and a Random object with seed 42. The first shuffle randomizes the list. By resetting the seed and shuffling again, we get identical results both times.

This technique is valuable when you need predictable randomness, such as in unit tests or when debugging shuffle-related issues. The same seed always produces the same shuffle order.

Shuffling a List of Custom Objects

Collections.shuffle works with any List implementation containing any object type. This example demonstrates shuffling a list of custom Person objects.

ShuffleCustomObjects.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

public class ShuffleCustomObjects {

    public static void main(String[] args) {
        
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 25));
        people.add(new Person("Bob", 30));
        people.add(new Person("Charlie", 22));
        people.add(new Person("Diana", 28));
        
        System.out.println("Original order:");
        people.forEach(System.out::println);
        
        Collections.shuffle(people);
        
        System.out.println("\nShuffled order:");
        people.forEach(System.out::println);
    }
}

We define a simple Person class with name and age fields. After creating and populating a list of Person objects, we shuffle it using Collections.shuffle. The output shows the random reordering.

This demonstrates that shuffle works with any object type, not just primitive wrappers or Strings. The Person objects maintain their integrity while their order in the list changes.

Shuffling Part of a List

To shuffle only a portion of a list, we can use List.subList to create a view of the desired range. This example shows how to shuffle just the first half of a list.

PartialShuffle.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PartialShuffle {

    public static void main(String[] args) {
        
        List<Integer> numbers = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            numbers.add(i);
        }
        
        System.out.println("Original list: " + numbers);
        
        // Shuffle first half
        int halfSize = numbers.size() / 2;
        Collections.shuffle(numbers.subList(0, halfSize));
        
        System.out.println("Half-shuffled: " + numbers);
    }
}

We create a list of numbers 1 through 10. Using subList(0, halfSize), we create a view of the first half of the list. Shuffling this sublist affects only those elements in the original list.

The output shows the first five numbers randomized while the last five remain in their original order. This technique is useful when you need to randomize only a specific section of a list.

Shuffling Arrays via List Conversion

While Collections.shuffle works on Lists, we can shuffle arrays by first converting them to a List. This example demonstrates the technique using Arrays.asList.

ShuffleArray.java
package com.zetcode;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ShuffleArray {

    public static void main(String[] args) {
        
        Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        
        System.out.println("Original array: " + Arrays.toString(numbers));
        
        // Convert to List and shuffle
        List<Integer> list = Arrays.asList(numbers);
        Collections.shuffle(list);
        
        System.out.println("Shuffled array: " + Arrays.toString(numbers));
    }
}

We create an Integer array (note: this won't work with primitive int arrays). Arrays.asList creates a List view of the array. Shuffling this list shuffles the underlying array.

The output shows the array elements in their new random order. Remember that Arrays.asList returns a fixed-size list backed by the array, so structural modifications aren't allowed.

Performance Considerations

This example compares the performance of shuffling different list implementations. ArrayList and LinkedList have different shuffle performance characteristics due to their internal structures.

ShufflePerformance.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class ShufflePerformance {

    static final int SIZE = 100000;
    
    public static void main(String[] args) {
        
        // Create lists
        List<Integer> arrayList = new ArrayList<>(SIZE);
        List<Integer> linkedList = new LinkedList<>();
        
        Random random = new Random();
        for (int i = 0; i < SIZE; i++) {
            int num = random.nextInt();
            arrayList.add(num);
            linkedList.add(num);
        }
        
        // Time ArrayList shuffle
        long start = System.currentTimeMillis();
        Collections.shuffle(arrayList);
        long duration = System.currentTimeMillis() - start;
        System.out.println("ArrayList shuffle time: " + duration + "ms");
        
        // Time LinkedList shuffle
        start = System.currentTimeMillis();
        Collections.shuffle(linkedList);
        duration = System.currentTimeMillis() - start;
        System.out.println("LinkedList shuffle time: " + duration + "ms");
    }
}

We populate an ArrayList and LinkedList with the same random numbers. We then time how long Collections.shuffle takes for each implementation. ArrayList is generally faster due to better memory locality.

The output shows the time difference between shuffling the two list types. For large lists, ArrayList can be significantly faster. Choose your list implementation based on your application's needs.

Thread-Safe Shuffling

This example demonstrates thread-safe shuffling using synchronized wrappers. When sharing collections between threads, proper synchronization is crucial to avoid concurrent modification issues.

ThreadSafeShuffle.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ThreadSafeShuffle {

    public static void main(String[] args) {
        
        List<String> unsafeList = new ArrayList<>();
        Collections.addAll(unsafeList, "A", "B", "C", "D", "E");
        
        // Create synchronized wrapper
        List<String> safeList = Collections.synchronizedList(unsafeList);
        
        // Shuffle safely in multi-threaded context
        synchronized (safeList) {
            Collections.shuffle(safeList);
            System.out.println("Shuffled safely: " + safeList);
        }
    }
}

We first create a regular ArrayList, then wrap it using Collections.synchronizedList. To perform the shuffle safely, we synchronize on the list object during the operation.

This ensures no other thread can modify the list during shuffling. While the synchronized wrapper provides thread-safe access, compound operations still require external synchronization.

Source

Java Collections.shuffle Documentation

In this tutorial, we've explored the Collections.shuffle method in depth. We've covered basic usage, custom randomness, performance considerations, and thread safety. Shuffling is a fundamental operation for many applications.

Author

My name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts.

List all Java tutorials.