为什么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
会导致asList
将int[]
视为单个对象而不是数组。 它返回List
而不是List
。 所以,你基本上是在改变单个元素List
,所以没有什么能真正被洗牌。
请注意,已经给出的一些答案是错误的,因为asList
返回由原始数组支持的List,没有任何内容被复制 – 所有更改都反映在原始数组中。
这不起作用,因为对shuffle
的调用是在Arrays.asList
返回的List
Arrays.asList
,而不是在底层数组上运行。 因此,当您遍历数组以打印出值时,没有任何更改。 你要做的是保存对Arrays.asList
返回的List
的Arrays.asList
,然后在你shuffle
之后打印出该List
的值(而不是数组的值)。
存储由Arrays.asList重新存储的列表并随机播放……
List myShuffledList = Arrays.asList(arr); Collections.shuffle(myShuffledList);