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

时间:2010-10-20 19:09:40

标签: java shuffle random-access

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

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 个答案:

答案 0 :(得分:43)

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

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

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

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

但是,后一个选项仅在T是引用类型(即不是基本类型,如int)时有效,因为只有引用类型可以用作泛型中的类型参数(和{ {1}}是一个类型参数)。

因此,如果您通过T,则会得到int[] = T,并且您的代码无法正常工作。但是如果您传递引用类型的数组(例如,int[]),则会得到Integer[] = T并且一切正常:

Integer

答案 1 :(得分:6)

尝试在测试中添加以下代码:

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

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

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

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

答案 2 :(得分:-2)

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

答案 3 :(得分:-3)

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

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