为什么Collections.shuffle()为我的数组失败?

为什么我的代码不起作用?

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] + " "); } } } 

其结果是:0 1 2 3 4 5 6 7 8 9。

我期待一个随机改组的序列。

Arrays.asList()不能像您期望的那样应用于基本类型的数组。 当应用于int[]Arrays.asList()生成一个int[] s列表而不是Integer列表。 因此,您随机播放新创建的int[]列表。

这是Java中可变参数和generics的微妙行为。 Arrays.asList()声明为

 public static  List asList(T... a) 

因此,它可以采用某些类型T几个参数并生成包含这些参数的列表,或者它可以采用类型为T[]一个参数并返回由此数组支持的列表(这是可变参数的工作方式)。

但是,后一个选项仅在T是引用类型(即不是诸如int的基本类型)时才起作用,因为只有引用类型可以用作generics中的类型参数(并且T是类型参数)。

因此,如果传递int[] ,则得到T = int[] ,并且代码不能按预期工作。 但是如果传递引用类型的数组(例如, Integer[] ),则得到T = Integer并且一切正常:

 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] + " "); } 

尝试将这行代码添加到您的测试中:

 List l=Arrays.asList(arr); System.out.println(l); 

您将看到打印出单个元素List

在原始数组上使用Arrays.asList会导致asListint[]视为单个对象而不是数组。 它返回List而不是List 。 所以,你基本上是在改变单个元素List ,所以没有什么能真正被洗牌。

请注意,已经给出的一些答案是错误的,因为asList返回由原始数组支持的List,没有任何内容被复制 – 所有更改都反映在原始数组中。

这不起作用,因为对shuffle的调用是在Arrays.asList返回的List Arrays.asList ,而不是在底层数组上运行。 因此,当您遍历数组以打印出值时,没有任何更改。 你要做的是保存对Arrays.asList返回的ListArrays.asList ,然后在你shuffle之后打印出该List的值(而不是数组的值)。

存储由Arrays.asList重新存储的列表并随机播放……

 List myShuffledList = Arrays.asList(arr); Collections.shuffle(myShuffledList);