Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Collections.shuffle() fail for my array?

Tags:

Why does my code not work?

package generatingInitialPopulation;  import java.util.Arrays; import java.util.Collections;  public class TestShuffle {     public static void main(String[] args) {         int[] arr = new int[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] + " ");         }     } } 

The result is: 0 1 2 3 4 5 6 7 8 9.

I was expecting a randomly shuffled sequence.

like image 385
Dmitry Avatar asked Oct 20 '10 19:10

Dmitry


People also ask

Can you shuffle an array?

Shuffle Array using Random Class We can iterate through the array elements in a for loop. Then, we use the Random class to generate a random index number. Then swap the current index element with the randomly generated index element. At the end of the for loop, we will have a randomly shuffled array.

Is shuffle available in collections class?

shuffle() method of Collections class as the class name suggests is present in utility package known as java. util that shuffles the elements in the list.

How do you shuffle elements in a collection?

The shuffle() is a Java Collections class method which works by randomly permuting the specified list elements. There is two different types of Java shuffle() method which can be differentiated depending on its parameter.

How do you shuffle values in an ArrayList?

In order to shuffle elements of ArrayList with Java Collections, we use the Collections. shuffle() method.


1 Answers

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 Integers. 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] + " ");  }  
like image 158
axtavt Avatar answered Sep 26 '22 21:09

axtavt