23

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

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。

我期待一个随机打乱的序列

4

4 回答 4

45

Arrays.asList()不能像您期望的那样应用于原始类型的数组。当应用于 时int[]Arrays.asList()生成 s 列表int[]而不是Integers 列表。因此,您将一个新创建的int[].

这是 Java 中可变参数和泛型的一种微妙行为。Arrays.asList()被声明为

public static <T> List<T> asList(T... a)

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

但是,后一个选项仅在T是引用类型(即不是原始类型,例如int)时才有效,因为只有引用类型可以用作泛型中的类型参数(并且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] + " "); 
} 
于 2010-10-20T19:20:02.023 回答
6

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

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

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

Arrays.asList在原始数组上使用会导致asList将其int[]视为单个对象而不是数组。它返回 aList<int[]>而不是 a List<Integer>。所以,你基本上是在洗牌一个元素List,所以没有什么东西真正被洗牌。

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

于 2010-10-20T19:28:20.977 回答
-2

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

于 2010-10-20T19:13:59.680 回答
-3

存储由 Arrays.asList 返回的列表并随机播放...

List myShuffledList = Arrays.asList(arr);
Collections.shuffle(myShuffledList);
于 2010-10-20T19:18:19.483 回答