Random shuffling of an array
JavaArraysRandomShuffleJava Problem Overview
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?
Java Solutions
Solution 1 - Java
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;
}
}
}
Solution 2 - Java
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);
Solution 3 - Java
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;
}
}
Solution 4 - Java
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;
}
}
Solution 5 - Java
Look at the Collections
class, specifically shuffle(...)
.
Solution 6 - Java
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>
).
Solution 7 - Java
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");
}
};
}
}
}
Solution 8 - Java
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);
Solution 9 - Java
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/
Solution 10 - Java
You can use java 8 now:
Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
Solution 11 - Java
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.
Solution 12 - Java
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
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.
Solution 13 - Java
Here is a solution using Apache Commons Math 3.x (for int[] arrays only):
MathArrays.shuffle(array);
Alternatively, Apache Commons Lang 3.6 introduced new shuffle methods to the ArrayUtils
class (for objects and any primitive type).
ArrayUtils.shuffle(array);
Solution 14 - Java
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
int[] intArr = {1,2,3};
List<Integer> integerList = Arrays.asList(ArrayUtils.toObject(array));
Collections.shuffle(integerList);
//now! elements in integerList are shuffled!
Solution 15 - Java
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.
Solution 16 - Java
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.
Solution 17 - Java
Using Guava's Ints.asList()
it is as simple as:
Collections.shuffle(Ints.asList(array));
Solution 18 - Java
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
}
}
Solution 19 - Java
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;
}
Solution 20 - Java
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]);
}
}
Solution 21 - Java
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
Solution 22 - Java
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]);
}
Solution 23 - Java
- Box from
int[]
toList<Integer>
- 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]
Solution 24 - Java
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));
}
}
Solution 25 - Java
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]
Solution 26 - Java
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);
}
}
}
Solution 27 - Java
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);
}
}
Solution 28 - Java
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);
Solution 29 - Java
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.
Solution 30 - Java
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));
}
Solution 31 - Java
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.