Why does Collections.shuffle() fail for my array?
Try adding this line of code to your test:
List l=Arrays.asList(arr);
System.out.println(l);
You will see you are printing out a single element List
.
Using Arrays.asList
on a primitive array cause asList
to treat the int[]
as a single object rather than an array. It returns a List<int[]>
instead of a List<Integer>
. So, you are basically shuffling a single element List
and so nothing really gets shuffled.
Notice that some of the answers already given are wrong because asList
returns a List backed by the original array, nothing gets copied - all changes are reflected in the orginal array.
Arrays.asList()
can't be applied to arrays of primitive type as you expect. When applied to int[]
, Arrays.asList()
produces a list of int[]
s instead of list of Integer
s. Therefore you shuffle a newly created list of int[]
.
This is a subtle behaviour of variadic arguments and generics in Java. Arrays.asList()
is declared as
public static <T> List<T> asList(T... a)
So, it can take several arguments of some type T
and produce a list containing these arguments, or it can take one argument of type T[]
and return a list backed by this array (that's how variadic arguments work).
However, the latter option works only when T
is a reference type (i.e. not a primitive type such as int
), because only reference types may be used as type parameters in generics (and T
is a type parameter).
So, if you pass int[]
, you get T
= int[]
, and you code doesn't work as expected. But if you pass array of reference type (for example, Integer[]
), you get T
= Integer
and everything works:
Integer[] arr = new Integer[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
Collections.shuffle(Arrays.asList(arr));
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}