282

I need to randomly shuffle the following Array:

int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};

Is there any function to do that?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Hubert
  • 16,012
  • 18
  • 45
  • 51
  • 9
    This is the SDK method you are looking for Collections.shuffle(Arrays.asList(array)); – Louis Hong Nov 05 '13 at 00:28
  • 4
    @Louie No, that doesn't work. That would create a `List` containing one entry. See [my answer](http://stackoverflow.com/a/21454317/474189) for the way to achieve this using `Collections.shuffle()`. – Duncan Jones Jan 30 '14 at 10:52
  • 2
    Not really an answer to the original question, but MathArrays.shuffle from the commons-math3 library does the job. – sandris Oct 29 '14 at 09:24
  • 3
    This is not on-topic enough to warrant an answer, but I remember a really cool article from "Graphics Gems" book that talked about traversing an array in pseudo random order. In my mind that beats having to actually shuffle the data in the first place. The C-implementation is found here https://github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.c – Mr. Developerdude Nov 15 '15 at 21:35
  • Also see this closely related question: http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array – Pierz Dec 02 '16 at 08:52
  • In case anyone who uses Kotlin comes across this question, the Kotlin standard library has `shuffle` methods for all kinds of primitive arrays. – k314159 Jun 23 '22 at 15:40

31 Answers31

296

Using Collections to shuffle an array of primitive types is a bit of an overkill...

It is simple enough to implement the function yourself, using for example the Fisher–Yates shuffle:

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

class Test
{
  public static void main(String args[])
  {
    int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 };

    shuffleArray(solutionArray);
    for (int i = 0; i < solutionArray.length; i++)
    {
      System.out.print(solutionArray[i] + " ");
    }
    System.out.println();
  }

  // Implementing Fisher–Yates shuffle
  static void shuffleArray(int[] ar)
  {
    // If running on Java 6 or older, use `new Random()` on RHS here
    Random rnd = ThreadLocalRandom.current();
    for (int i = ar.length - 1; i > 0; i--)
    {
      int index = rnd.nextInt(i + 1);
      // Simple swap
      int a = ar[index];
      ar[index] = ar[i];
      ar[i] = a;
    }
  }
}
leventov
  • 14,760
  • 11
  • 69
  • 98
PhiLho
  • 40,535
  • 6
  • 96
  • 134
  • @PhiLho How is it different than java collections's shuffle? – AKS Aug 20 '13 at 22:14
  • 1
    @AKS the difference is that here, you shuffle a simple array, while Java Collections, by definition, shuffles a Collection... Putting the array in a list to shuffle it and getting back the array is, as I wrote, a bit of overkill. – PhiLho Aug 27 '13 at 10:20
  • @DanBray Right and wrong. Right on the bound of the loop, indeed, it should end with i at 1. I will edit that, thanks. Wrong, as (i + 1) is needed, see the Wikipedia article, particularly the Implementation errors section... – PhiLho Aug 27 '13 at 10:34
  • @PhiLho you are right Phil. `(i + 1)` doesn't work because I am using the XOR method to swap the variables and when the variables are the same, both variables are set to 0. I'll update the code I posted. – Dan Bray Aug 27 '13 at 20:30
  • 72
    It'd be much better to use Collections.shuffle(Arrays.asList(array)); then making a shuffle your self. – Louis Hong Nov 05 '13 at 00:12
  • 27
    @Louie `Collections.shuffle(Arrays.asList(array))` doesn't work, because `Arrays.asList(array)` returns `Collection` not `Collection` as you thought. – Adam Stelmaszczyk Dec 13 '13 at 12:33
  • 3
    Why is `Collections.shuffle` overkill? – exhuma May 05 '14 at 13:26
  • 19
    @exhuma Because if you have an array of thousands or millions of primitive values to sort, wrapping each one in an object just to do a sort is a bit costly, both in memory and in CPU. – PhiLho Jul 11 '14 at 11:11
  • 16
    This is **not** the Fisher-Yates shuffle. This is called [Durstenfeld shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm). The original fisher-yates shuffle runs in O(n^2) time which is extremely slow. – Pacerier Oct 31 '14 at 12:39
  • @PhiLho could you tell me why we need to do "int index = rnd.nextInt(i + 1);" instead of simply doing "int index = rnd.nextInt(ar.length);"? – CSnerd Aug 20 '16 at 07:11
  • 1
    @CSnerd I suggest to follow my link to the Wikipedia page which will explain this better than myself in a comment... – PhiLho Aug 22 '16 at 10:12
  • What if I wanted to use the same method to shuffle arrays of ints and arrays of strings? – ShoeLace1291 Oct 27 '16 at 17:08
  • 2
    @ShoeLace1291 If I am not mistaken, you cannot in Java: there is no way to make a method working generically with primitives (int) and objects (strings). You have to duplicate it. – PhiLho Oct 28 '16 at 10:24
  • @Adam Stelmaszczyk you raised a good point. but `Arrays.asList(array)` does not return `Collection` it returns `int[]` primitives can not be in generic type. – Vishrant Feb 16 '17 at 00:13
  • would it be wrong to use `Random` instead of `ThreadLocalRandom` or is it only a matter of overhead/ performance? – ericn Jul 06 '17 at 00:34
  • 1
    @ericn The change was introduced by leventov, it was `new Random()` before... I think the purpose is to be safe in case the code is used by several threads, as they won't wait for the availability of the global Random in turns. I don't this there is a difference with a single thread, but it looks like the always safe option. – PhiLho Jul 08 '17 at 17:57
189

Here is a simple way using an ArrayList:

List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
    solution.add(i);
}
Collections.shuffle(solution);
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
methodin
  • 6,717
  • 1
  • 25
  • 27
109

Here is a working and efficient Fisher–Yates shuffle array function:

private static void shuffleArray(int[] array)
{
    int index;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        if (index != i)
        {
            array[index] ^= array[i];
            array[i] ^= array[index];
            array[index] ^= array[i];
        }
    }
}

or

private static void shuffleArray(int[] array)
{
    int index, temp;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        temp = array[index];
        array[index] = array[i];
        array[i] = temp;
    }
}
Flowi
  • 45
  • 4
Dan Bray
  • 7,242
  • 3
  • 52
  • 70
  • 1
    Voted up because I needed a solution that did not have the high overhead of creating a Collection of Integer – mwk Sep 30 '13 at 17:27
  • 2
    Doesn't the second implementation have the potential to swap with its own index? `random.nextInt(int bound)` is exclusive but giving it `i + 1` as an argument would allow `index` and `i` to potentially be the same. – bmcentee148 May 27 '15 at 02:42
  • 34
    @bmcentee148 Swapping an element with itself is permissible in a random ordering. Not understanding this weakened the Enigma and helped enable Alan Turing to crack it. https://en.wikipedia.org/wiki/Cryptanalysis_of_the_Enigma#The_Enigma_machines – Ellen Spertus Jun 09 '15 at 23:59
  • 6
    The `xor` trick is great for swapping CPU registers when the CPU has no swap instruction and there are no free registers, but for swapping array elements inside a loop, I don’t see any benefit. For the temporary local variables, there is no reason to declare them outside the loop. – Holger Jan 06 '17 at 18:46
  • 1
    It's slightly more efficient to declare the `temp` variable outside of the loop. The `XOR` trick should be faster than using a `temp` variable but the only way to be sure it to perform a benchmark test. – Dan Bray Jan 06 '17 at 20:08
  • The second variant can be genericized for array based shuffling of complex objects. e.g. `static void shuffle(V[] array, Random random)` – LateralFractal Jan 25 '17 at 07:12
  • @DanBray It's quicker if the compiler doesn't do it on it's own accord, which would make sense since that's semantically equivalent and easy to spot – Nearoo Mar 09 '21 at 10:10
30

Collections class has an efficient method for shuffling, that can be copied, so as not to depend on it:

/**
 * Usage:
 *    int[] array = {1, 2, 3};
 *    Util.shuffle(array);
 */
public class Util {

    private static Random random;

    /**
     * Code from method java.util.Collections.shuffle();
     */
    public static void shuffle(int[] array) {
        if (random == null) random = new Random();
        int count = array.length;
        for (int i = count; i > 1; i--) {
            swap(array, i - 1, random.nextInt(i));
        }
    }

    private static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}
KitKat
  • 1,495
  • 14
  • 15
  • *so as not to depend on it*? I'd much prefer to depend on it, if that were only possible. – shmosel Feb 23 '17 at 21:18
  • @shmosel Then feel free to use it. Make sure you import the required class and you have converted the array to a list with `Arrays.asList`. You have to convert the resulting list to an array, too – KitKat Jun 09 '18 at 16:50
  • 3
    You can't use `Arrays.asList()` on a primitive array. And you wouldn't need to convert it back because it's just a wrapper. – shmosel Jun 10 '18 at 04:12
14

Look at the Collections class, specifically shuffle(...).

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
Dave
  • 6,064
  • 4
  • 31
  • 38
  • 8
    How do you use this Collections class in Android ? You need to do a special import (CRTL SHIFT O doesn't work) to use it ? – Hubert Oct 05 '09 at 12:23
  • @Hubert it should be part of the package `java.util`. It's part of the standard library since v1.2. – MauganRa Feb 02 '17 at 16:04
  • 3
    To make your answer more self contained, it should contain example code. IE: `import java.util.Collections; shuffle(solutionArray);` – Stevoisiak Apr 23 '17 at 17:49
12

You have a couple options here. A list is a bit different than an array when it comes to shuffling.

As you can see below, an array is faster than a list, and a primitive array is faster than an object array.

Sample Durations

List<Integer> Shuffle: 43133ns
    Integer[] Shuffle: 31884ns
        int[] Shuffle: 25377ns

Below, are three different implementations of a shuffle. You should only use Collections.shuffle if you are dealing with a collection. There is no need to wrap your array into a collection just to sort it. The methods below are very simple to implement.

ShuffleUtil Class

import java.lang.reflect.Array;
import java.util.*;

public class ShuffleUtil<T> {
    private static final int[] EMPTY_INT_ARRAY = new int[0];
    private static final int SHUFFLE_THRESHOLD = 5;

    private static Random rand;

Main Method

    public static void main(String[] args) {
        List<Integer> list = null;
        Integer[] arr = null;
        int[] iarr = null;

        long start = 0;
        int cycles = 1000;
        int n = 1000;

        // Shuffle List<Integer>
        start = System.nanoTime();
        list = range(n);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(list);
        }
        System.out.printf("%22s: %dns%n", "List<Integer> Shuffle", (System.nanoTime() - start) / cycles);

        // Shuffle Integer[]
        start = System.nanoTime();
        arr = toArray(list);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(arr);
        }
        System.out.printf("%22s: %dns%n", "Integer[] Shuffle", (System.nanoTime() - start) / cycles);

        // Shuffle int[]
        start = System.nanoTime();
        iarr = toPrimitive(arr);
        for (int i = 0; i < cycles; i++) {
            ShuffleUtil.shuffle(iarr);
        }
        System.out.printf("%22s: %dns%n", "int[] Shuffle", (System.nanoTime() - start) / cycles);
    }

Shuffling a Generic List

    // ================================================================
    // Shuffle List<T> (java.lang.Collections)
    // ================================================================
    @SuppressWarnings("unchecked")
    public static <T> void shuffle(List<T> list) {
        if (rand == null) {
            rand = new Random();
        }
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i = size; i > 1; i--) {
                swap(list, i - 1, rand.nextInt(i));
            }
        } else {
            Object arr[] = list.toArray();

            for (int i = size; i > 1; i--) {
                swap(arr, i - 1, rand.nextInt(i));
            }

            ListIterator<T> it = list.listIterator();
            int i = 0;

            while (it.hasNext()) {
                it.next();
                it.set((T) arr[i++]);
            }
        }
    }

    public static <T> void swap(List<T> list, int i, int j) {
        final List<T> l = list;
        l.set(i, l.set(j, l.get(i)));
    }

    public static <T> List<T> shuffled(List<T> list) {
        List<T> copy = copyList(list);
        shuffle(copy);
        return copy;
    }

Shuffling a Generic Array

    // ================================================================
    // Shuffle T[]
    // ================================================================
    public static <T> void shuffle(T[] arr) {
        if (rand == null) {
            rand = new Random();
        }

        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, i, rand.nextInt(i + 1));
        }
    }

    public static <T> void swap(T[] arr, int i, int j) {
        T tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static <T> T[] shuffled(T[] arr) {
        T[] copy = Arrays.copyOf(arr, arr.length);
        shuffle(copy);
        return copy;
    }

Shuffling a Primitive Array

    // ================================================================
    // Shuffle int[]
    // ================================================================
    public static <T> void shuffle(int[] arr) {
        if (rand == null) {
            rand = new Random();
        }

        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, i, rand.nextInt(i + 1));
        }
    }

    public static <T> void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static int[] shuffled(int[] arr) {
        int[] copy = Arrays.copyOf(arr, arr.length);
        shuffle(copy);
        return copy;
    }

Utility Methods

Simple utility methods to copy and convert arrays to lists and vice-versa.

    // ================================================================
    // Utility methods
    // ================================================================
    protected static <T> List<T> copyList(List<T> list) {
        List<T> copy = new ArrayList<T>(list.size());
        for (T item : list) {
            copy.add(item);
        }
        return copy;
    }

    protected static int[] toPrimitive(Integer[] array) {
        if (array == null) {
            return null;
        } else if (array.length == 0) {
            return EMPTY_INT_ARRAY;
        }
        final int[] result = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            result[i] = array[i].intValue();
        }
        return result;
    }

    protected static Integer[] toArray(List<Integer> list) {
        return toArray(list, Integer.class);
    }

    protected static <T> T[] toArray(List<T> list, Class<T> clazz) {
        @SuppressWarnings("unchecked")
        final T[] arr = list.toArray((T[]) Array.newInstance(clazz, list.size()));
        return arr;
    }

Range Class

Generates a range of values, similar to Python's range function.

    // ================================================================
    // Range class for generating a range of values.
    // ================================================================
    protected static List<Integer> range(int n) {
        return toList(new Range(n), new ArrayList<Integer>());
    }

    protected static <T> List<T> toList(Iterable<T> iterable) {
        return toList(iterable, new ArrayList<T>());
    }

    protected static <T> List<T> toList(Iterable<T> iterable, List<T> destination) {
        addAll(destination, iterable.iterator());

        return destination;
    }

    protected static <T> void addAll(Collection<T> collection, Iterator<T> iterator) {
        while (iterator.hasNext()) {
            collection.add(iterator.next());
        }
    }

    private static class Range implements Iterable<Integer> {
        private int start;
        private int stop;
        private int step;

        private Range(int n) {
            this(0, n, 1);
        }

        private Range(int start, int stop) {
            this(start, stop, 1);
        }

        private Range(int start, int stop, int step) {
            this.start = start;
            this.stop = stop;
            this.step = step;
        }

        @Override
        public Iterator<Integer> iterator() {
            final int min = start;
            final int max = stop / step;

            return new Iterator<Integer>() {
                private int current = min;

                @Override
                public boolean hasNext() {
                    return current < max;
                }

                @Override
                public Integer next() {
                    if (hasNext()) {
                        return current++ * step;
                    } else {
                        throw new NoSuchElementException("Range reached the end");
                    }
                }

                @Override
                public void remove() {
                    throw new UnsupportedOperationException("Can't remove values from a Range");
                }
            };
        }
    }
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • 2
    You are not timing the same things and you're timing each one only once (then their order counts & you forget the runtime optimization). You should call `range`, `toArray` and `toPrimitive` before any timing, and loop to be able to conclude anything (pseudo-code: do several times { generate list, arr and iarr; time shuffling list; time shuffling arr; time shuffling iarr }). My results: 1st: `list: 36017ns, arr: 28262ns, iarr: 23334ns`. 100th: `list: 18445ns, arr: 19995ns, iarr: 18657ns`. It just shows int[] is pre-optimized (by code) but they're almost equivalent with runtime optimization. – syme Jul 03 '16 at 13:05
11

Here is a complete solution using the Collections.shuffle approach:

public static void shuffleArray(int[] array) {
  List<Integer> list = new ArrayList<>();
  for (int i : array) {
    list.add(i);
  }

  Collections.shuffle(list);

  for (int i = 0; i < list.size(); i++) {
    array[i] = list.get(i);
  }    
}

Note that it suffers due to Java's inability to smoothly translate between int[] and Integer[] (and thus int[] and List<Integer>).

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
9

Using ArrayList<Integer> can help you solving the problem of shuffling without applying much of logic and consuming less time. Here is what I suggest:

ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
    x.add(i);
}
Collections.shuffle(x);
Wolf
  • 9,679
  • 7
  • 62
  • 108
SalmaanKhan
  • 811
  • 7
  • 4
9

The following code will achieve a random ordering on the array.

// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));

from: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/

Murray Foxcroft
  • 12,785
  • 7
  • 58
  • 86
Rajib Biswas
  • 146
  • 1
  • 5
5

You can use java 8 now:

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • 3
    There is nothing Java8-specific in this code. This works since Java2. Well, it would work, once you fix the inconsistency between first using `list` and suddenly referring to `cardsList`. But since you need to create the temporary `list`, which you have omitted, there is no benefit over the `Collections.shuffle(Arrays.asList(arr));` approach shown several times here. Which also works since Java2. – Holger Jan 06 '17 at 18:52
4
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
  int index = rnd.nextInt(i + 1);
  // Simple swap
  int a = ar[index];
  ar[index] = ar[i];
  ar[i] = a;
}

By the way, I've noticed that this code returns a ar.length - 1 number of elements, so if your array has 5 elements, the new shuffled array will have 4 elements. This happens because the for loop says i>0. If you change to i>=0, you get all elements shuffled.

Matt
  • 45,022
  • 8
  • 78
  • 119
  • Just a heads up, you may want to move this to the comment section of your question, since it will probably get flagged if it's left as its own answer. – Jason D Nov 15 '14 at 15:38
  • 1
    This seems to answer the question, so I am unsure what you are talking about @JasonD – Sumurai8 Nov 15 '14 at 16:42
  • 1
    The code is correct, the comment is wrong. If you change ```i>0``` to ```i>=0```, you waste time by swapping element ```0``` with itself. – jcsahnwaldt Reinstate Monica Mar 20 '16 at 16:33
4

Here is a solution using Apache Commons Math 3.x (for int[] arrays only):

MathArrays.shuffle(array);

http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle(int[])

Alternatively, Apache Commons Lang 3.6 introduced new shuffle methods to the ArrayUtils class (for objects and any primitive type).

ArrayUtils.shuffle(array);

http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-

Emmanuel Bourg
  • 9,601
  • 3
  • 48
  • 76
3

Here is a Generics version for arrays:

import java.util.Random;

public class Shuffle<T> {

    private final Random rnd;

    public Shuffle() {
        rnd = new Random();
    }

    /**
     * Fisher–Yates shuffle.
     */
    public void shuffle(T[] ar) {
        for (int i = ar.length - 1; i > 0; i--) {
            int index = rnd.nextInt(i + 1);
            T a = ar[index];
            ar[index] = ar[i];
            ar[i] = a;
        }
    }
}

Considering that ArrayList is basically just an array, it may be advisable to work with an ArrayList instead of the explicit array and use Collections.shuffle(). Performance tests however, do not show any significant difference between the above and Collections.sort():

Shuffe<Integer>.shuffle(...) performance: 576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance: 629400 shuffles per second
MathArrays.shuffle(int[]) performance: 53062 shuffles per second

The Apache Commons implementation MathArrays.shuffle is limited to int[] and the performance penalty is likely due to the random number generator being used.

user1050755
  • 11,218
  • 4
  • 45
  • 56
  • 1
    It looks like you can pass `new JDKRandomGenerator()` to `MathArrays.shuffle`. I wonder how that affects the performance? – Brandon Dec 16 '16 at 21:34
  • Actually... it looks like `MathArrays#shuffle` has an allocation in its core loop: `int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();`. Bizarre. – Brandon Dec 16 '16 at 21:40
3

I saw some miss information in some answers so i decided to add a new one.

Java collections Arrays.asList takes var-arg of type T (T ...). If you pass a primitive array (int array), asList method will infer and generate a List<int[]>, which is a one element list (the one element is the primitive array). if you shuffle this one element list, it won`t change any thing.

So, first you have to convert you primitive array to Wrapper object array. for this you can use ArrayUtils.toObject method from apache.commons.lang. then pass the generated array to a List and finaly shuffle that.

  int[] intArr = {1,2,3};
  List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
  Collections.shuffle(integerList);
  //now! elements in integerList are shuffled!
Mr.Q
  • 4,316
  • 3
  • 43
  • 40
3

Here's another way to shuffle a list

public List<Integer> shuffleArray(List<Integer> a) {
    List<Integer> b = new ArrayList<Integer>();
    while (a.size() != 0) {
        int arrayIndex = (int) (Math.random() * (a.size()));
        b.add(a.get(arrayIndex));
        a.remove(a.get(arrayIndex));
    }
    return b;
}

Pick a random number from the original list and save it in another list.Then remove the number from the original list.The size of the original list will keep decreasing by one until all elements are moved to the new list.

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
PS5
  • 41
  • 3
2

A simple solution for Groovy:

solutionArray.sort{ new Random().nextInt() }

This will sort all elements of the array list randomly which archives the desired result of shuffling all elements.

Hans Kristian
  • 1,786
  • 19
  • 25
2

Using Guava's Ints.asList() it is as simple as:

Collections.shuffle(Ints.asList(array));
BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
2

Using the Random Class

  public static void randomizeArray(int[] arr) {

      Random rGenerator = new Random(); // Create an instance of the random class 
      for (int i =0; i< arr.length;i++ ) {
          //Swap the positions...

          int rPosition = rGenerator.nextInt(arr.length); // Generates an integer within the range (Any number from 0 - arr.length)
          int temp = arr[i]; // variable temp saves the value of the current array index;
          arr[i] = arr[rPosition];  // array at the current position (i) get the value of the random generated 
          arr[rPosition] = temp; // the array at the position of random generated gets the value of temp

      }

      for(int i = 0; i<arr.length; i++) {
          System.out.print(arr[i]); //Prints out the array
      } 

  }
1

I'm weighing in on this very popular question because nobody has written a shuffle-copy version. Style is borrowed heavily from Arrays.java, because who isn't pillaging Java technology these days? Generic and int implementations included.

   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   @SuppressWarnings("unchecked")
   public static <T> T[] shuffledCopy(T[] original) {
      int originalLength = original.length; // For exception priority compatibility.
      Random random = new Random();
      T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), originalLength);

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }


   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   public static int[] shuffledCopy(int[] original) {
      int originalLength = original.length;
      Random random = new Random();
      int[] result = new int[originalLength];

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }
QED
  • 9,803
  • 7
  • 50
  • 87
1

This is knuth shuffle algorithm.

public class Knuth { 

    // this class should not be instantiated
    private Knuth() { }

    /**
     * Rearranges an array of objects in uniformly random order
     * (under the assumption that <tt>Math.random()</tt> generates independent
     * and uniformly distributed numbers between 0 and 1).
     * @param a the array to be shuffled
     */
    public static void shuffle(Object[] a) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            // choose index uniformly in [i, n-1]
            int r = i + (int) (Math.random() * (n - i));
            Object swap = a[r];
            a[r] = a[i];
            a[i] = swap;
        }
    }

    /**
     * Reads in a sequence of strings from standard input, shuffles
     * them, and prints out the results.
     */
    public static void main(String[] args) {

        // read in the data
        String[] a = StdIn.readAllStrings();

        // shuffle the array
        Knuth.shuffle(a);

        // print results.
        for (int i = 0; i < a.length; i++)
            StdOut.println(a[i]);
    }
}
BufBills
  • 8,005
  • 12
  • 48
  • 90
1

There is another way also, not post yet

//that way, send many object types diferentes
public anotherWayToReciveParameter(Object... objects)
{
    //ready with array
    final int length =objects.length;
    System.out.println(length);
    //for ready same list
    Arrays.asList(objects);
}

that way more easy, depended of the context

Marcelo Ferreira
  • 428
  • 1
  • 5
  • 20
1

The most simple solution for this Random Shuffling in an Array.

String location[] = {"delhi","banglore","mathura","lucknow","chandigarh","mumbai"};
int index;
String temp;
Random random = new Random();
for(int i=1;i<location.length;i++)
{
    index = random.nextInt(i+1);
    temp = location[index];
    location[index] = location[i];
    location[i] = temp;
    System.out.println("Location Based On Random Values :"+location[i]);
}
Thewads
  • 4,953
  • 11
  • 55
  • 71
Archit Goel
  • 85
  • 1
  • 2
1
  1. Box from int[] to List<Integer>
  2. Shuffle with Collections.shuffle method
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };

List<Integer> list = Arrays.stream(solutionArray).boxed().collect(Collectors.toList());
Collections.shuffle(list);

System.out.println(list.toString());
// [1, 5, 5, 4, 2, 6, 1, 3, 3, 4, 2, 6]
YujiSoftware
  • 1,281
  • 14
  • 15
1

Simplest code to shuffle:

import java.util.*;
public class ch {
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        ArrayList<Integer> l=new ArrayList<Integer>(10);
        for(int i=0;i<10;i++)
            l.add(sc.nextInt());
        Collections.shuffle(l);
        for(int j=0;j<10;j++)
            System.out.println(l.get(j));       
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
suraj
  • 11
  • 1
1

You should use Collections.shuffle(). However, you can't directly manipulate an array of primitive types, so you need to create a wrapper class.

Try this.

public static void shuffle(int[] array) {
    Collections.shuffle(new AbstractList<Integer>() {
        @Override public Integer get(int index) { return array[index]; }
        @Override public int size() { return array.length; }
        @Override public Integer set(int index, Integer element) {
            int result = array[index];
            array[index] = element;
            return result;
        }
    });
}

And

int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};
shuffle(solutionArray);
System.out.println(Arrays.toString(solutionArray));

output:

[3, 3, 4, 1, 6, 2, 2, 1, 5, 6, 5, 4]
0
public class ShuffleArray {
public static void shuffleArray(int[] a) {
    int n = a.length;
    Random random = new Random();
    random.nextInt();
    for (int i = 0; i < n; i++) {
        int change = i + random.nextInt(n - i);
        swap(a, i, change);
    }
}

private static void swap(int[] a, int i, int change) {
    int helper = a[i];
    a[i] = a[change];
    a[change] = helper;
}

public static void main(String[] args) {
    int[] a = new int[] { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 };
    shuffleArray(a);
    for (int i : a) {
        System.out.println(i);
    }
}
}
always-a-learner
  • 3,671
  • 10
  • 41
  • 81
0
import java.util.ArrayList;
import java.util.Random;
public class shuffle {
    public static void main(String[] args) {
        int a[] =  {1,2,3,4,5,6,7,8,9};
         ArrayList b = new ArrayList();
       int i=0,q=0;
       Random rand = new Random();

       while(a.length!=b.size())
       {
           int l = rand.nextInt(a.length);
//this is one option to that but has a flaw on 0
//           if(a[l] !=0)
//           {
//                b.add(a[l]);
//               a[l]=0;
//               
//           }
//           
// this works for every no. 
                if(!(b.contains(a[l])))
                {
                    b.add(a[l]);
                }



       }

//        for (int j = 0; j <b.size(); j++) {
//            System.out.println(b.get(j));
//            
//        }
System.out.println(b);
    }

}
0

similar without using swap b

    Random r = new Random();
    int n = solutionArray.length;
    List<Integer> arr =  Arrays.stream(solutionArray)
                               .boxed()
                               .collect(Collectors.toList());
    for (int i = 0; i < n-1; i++) {
        solutionArray[i] = arr.remove(r.nextInt(arr.size())); // randomize based on size
    }
    solutionArray[n-1] = arr.get(0);
Jeffin Manuel
  • 542
  • 1
  • 6
  • 18
digitebs
  • 834
  • 8
  • 10
0

One of the solution is using the permutation to pre-compute all the permutations and stored in the ArrayList

Java 8 introduced a new method, ints(), in the java.util.Random class. The ints() method returns an unlimited stream of pseudorandom int values. You can limit the random numbers between a specified range by providing the minimum and the maximum values.

Random genRandom = new Random();
int num = genRandom.nextInt(arr.length);

With the help of generating the random number, You can iterate through the loop and swap with the current index with the random number.. That's how you can generate a random number with O(1) space complexity.

0

In Java we can use Collections.shuffle method to randomly reorder items in a list.

Groovy 3.0.0 adds the shuffle and shuffled methods to a List or array directly.

demon101
  • 544
  • 1
  • 11
  • 39
-1

Without Random solution:

   static void randomArrTimest(int[] some){
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < some.length; i++) {
            long indexToSwap = startTime%(i+1);
            long tmp = some[(int) indexToSwap];
            some[(int) indexToSwap] = some[i];
            some[i] = (int) tmp;
        }
        System.out.println(Arrays.toString(some));
    }
izum286
  • 25
  • 7