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

2022-09-01 22:38:50

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

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。

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


答案 1

Arrays.asList()不能像预期的那样应用于基元类型的数组。当应用于 时,将生成 s 的列表,而不是 s 的列表。因此,您可以随机排列新创建的 .int[]Arrays.asList()int[]Integerint[]

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

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

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

但是,后一个选项仅在 引用类型(即不是基元类型,如 )时才有效,因为只有引用类型可以用作泛型中的类型参数(并且是类型参数)。TintT

因此,如果您通过 ,则得到 = ,并且您的代码无法按预期工作。但是如果你传递引用类型的数组(例如,),你会得到=,一切都有效:int[]Tint[]Integer[]TInteger

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

答案 2

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

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

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

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

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