Random shuffling of an array
Asked Answered
V

31

283

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?

Victor answered 5/10, 2009 at 12:15 Comment(6)
This is the SDK method you are looking for Collections.shuffle(Arrays.asList(array));Bettiebettina
@Louie No, that doesn't work. That would create a List<int[]> containing one entry. See my answer for the way to achieve this using Collections.shuffle().Iodate
Not really an answer to the original question, but MathArrays.shuffle from the commons-math3 library does the job.Efflux
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 github.com/erich666/GraphicsGems/blob/master/gems/Dissolve.cDiastyle
Also see this closely related question: #2451454Trelliswork
In case anyone who uses Kotlin comes across this question, the Kotlin standard library has shuffle methods for all kinds of primitive arrays.Chaps
B
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.*;

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)
  {
    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;
    }
  }
}
Beauchamp answered 5/10, 2009 at 13:53 Comment(17)
@Beauchamp How is it different than java collections's shuffle?Taub
@Taub 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.Beauchamp
@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...Beauchamp
@Beauchamp 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.Ashlaring
It'd be much better to use Collections.shuffle(Arrays.asList(array)); then making a shuffle your self.Bettiebettina
@Louie Collections.shuffle(Arrays.asList(array)) doesn't work, because Arrays.asList(array) returns Collection<int[]> not Collection<Integer> as you thought.Marcelo
Why is Collections.shuffle overkill?Hedelman
@Hedelman 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.Beauchamp
This is not the Fisher-Yates shuffle. This is called Durstenfeld shuffle. The original fisher-yates shuffle runs in O(n^2) time which is extremely slow.Delapaz
@Beauchamp 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);"?Ruddy
@Ruddy I suggest to follow my link to the Wikipedia page which will explain this better than myself in a comment...Beauchamp
What if I wanted to use the same method to shuffle arrays of ints and arrays of strings?Fineness
@Fineness 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.Beauchamp
@Adam Stelmaszczyk you raised a good point. but Arrays.asList(array) does not return Collection<int[]> it returns int[] primitives can not be in generic type.Georgia
would it be wrong to use Random instead of ThreadLocalRandom or is it only a matter of overhead/ performance?Pharmaceutical
@Pharmaceutical 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.Beauchamp
@Pharmaceutical @Beauchamp I removed ThreadLocalRandom. Simply using Random is fine here. ThreadLocalRandom is recommended when a single Random instance is used by multiple thread, but here we create a Random object, use it in a single thread, and then forget about it.Isleana
M
190

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);
Ml answered 17/9, 2010 at 1:23 Comment(2)
You can simply Collectons.shuffle(Arrays.asList(solutionArray));Morten
What's going on with this answer. It doesn't even attempt to answer the question in the title. There aren't even any arrays anywhere in sight.Wieche
A
110

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;
    }
}
Ashlaring answered 27/8, 2013 at 4:34 Comment(7)
Voted up because I needed a solution that did not have the high overhead of creating a Collection of IntegerRosie
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.Urbanity
@Urbanity 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. en.wikipedia.org/wiki/…Butacaine
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.Cooley
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.Ashlaring
The second variant can be genericized for array based shuffling of complex objects. e.g. static <V> void shuffle(V[] array, Random random)Emanation
@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 spotAmphioxus
A
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;
    }
}
Alcorn answered 12/10, 2013 at 10:33 Comment(3)
so as not to depend on it? I'd much prefer to depend on it, if that were only possible.Foucquet
@Foucquet 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, tooAlcorn
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.Foucquet
P
14

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

Po answered 5/10, 2009 at 12:18 Comment(3)
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 ?Victor
@Victor it should be part of the package java.util. It's part of the standard library since v1.2.Shocker
To make your answer more self contained, it should contain example code. IE: import java.util.Collections; shuffle(solutionArray);Assay
M
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");
                }
            };
        }
    }
}
Mcgee answered 30/11, 2015 at 20:39 Comment(1)
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.Surfboat
I
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>).

Iodate answered 30/1, 2014 at 10:50 Comment(0)
C
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);
Corm answered 20/11, 2013 at 4:53 Comment(2)
Probably not the latter - consuming less time. In fact this is certainly slower than the primitive implementations above.Wellborn
For someone copies the code, watch the "for cycle" i=1 maybe you need i=0Eisenach
A
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/

Angele answered 2/8, 2016 at 6:12 Comment(2)
be aware that it doesn't work on primitive arrays, because Arrays.asList treat primitive array as one elementWaine
how about if the array is containing many objects instead of usual primitive array?Likelihood
A
5

You can use java 8 now:

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Authorship answered 24/4, 2016 at 8:22 Comment(1)
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.Cooley
P
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.

Polluted answered 15/11, 2014 at 15:35 Comment(3)
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.Hesitant
This seems to answer the question, so I am unsure what you are talking about @JasonDQuidnunc
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.Isleana
M
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-

Mortenson answered 27/9, 2016 at 20:51 Comment(0)
K
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.

Kurtzig answered 4/11, 2014 at 8:5 Comment(2)
It looks like you can pass new JDKRandomGenerator() to MathArrays.shuffle. I wonder how that affects the performance?Appointed
Actually... it looks like MathArrays#shuffle has an allocation in its core loop: int targetIdx = new UniformIntegerDistribution(rng, start, i).sample();. Bizarre.Appointed
R
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!
Redbird answered 26/7, 2017 at 10:59 Comment(0)
S
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.

Sneck answered 9/3, 2018 at 11:10 Comment(0)
L
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.

Lustig answered 7/12, 2017 at 7:49 Comment(0)
L
2

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

Collections.shuffle(Ints.asList(array));
Lith answered 6/6, 2019 at 22:16 Comment(0)
P
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
      } 

  }
Piotr answered 14/5, 2020 at 17:23 Comment(0)
C
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;
   }
Corked answered 31/5, 2016 at 21:11 Comment(0)
R
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]);
    }
}
Roobbie answered 15/8, 2016 at 14:57 Comment(0)
G
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

Glitter answered 27/10, 2016 at 17:42 Comment(0)
S
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]);
}
Synthesize answered 5/7, 2017 at 8:10 Comment(0)
M
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]
Microcosm answered 17/2, 2018 at 10:22 Comment(0)
O
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));       
    }
}
Outwash answered 6/4, 2018 at 10:4 Comment(0)
P
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]
Posthaste answered 27/3, 2021 at 22:0 Comment(0)
R
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);
    }
}
}
Replevin answered 26/9, 2017 at 12:34 Comment(1)
Please add some related description regarding your answer.Localize
S
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);
    }

}
Shaniceshanie answered 28/6, 2018 at 5:27 Comment(0)
L
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);
Lonilonier answered 1/2, 2019 at 8:49 Comment(0)
D
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.

Dillard answered 27/2, 2019 at 5:15 Comment(0)
C
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.

Cognoscenti answered 27/4, 2021 at 8:27 Comment(0)
H
-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));
    }
Hegarty answered 23/3, 2020 at 10:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.