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

发布于 2024-09-28 01:19:38 字数 564 浏览 6 评论 0原文

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

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。

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

Why does my code not work?

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

The result is: 0 1 2 3 4 5 6 7 8 9.

I was expecting a randomly shuffled sequence.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

最近可好 2024-10-05 01:19:38

Arrays.asList() 不能像您期望的那样应用于原始类型的数组。当应用于 int[] 时,Arrays.asList() 会生成 int[] 列表,而不是 Integer< 列表/代码>s。因此,您对新创建的 int[] 列表进行洗牌。

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

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

因此,它可以采用某种类型 T 的多个参数并生成包含这些参数的列表,或者它可以采用 T 类型的一个参数code>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] + " "); 
} 

Arrays.asList() can't be applied to arrays of primitive type as you expect. When applied to int[], Arrays.asList() produces a list of int[]s instead of list of Integers. Therefore you shuffle a newly created list of int[].

This is a subtle behaviour of variadic arguments and generics in Java. Arrays.asList() is declared as

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

So, it can take several arguments of some type T and produce a list containing these arguments, or it can take one argument of type T[] and return a list backed by this array (that's how variadic arguments work).

However, the latter option works only when T is a reference type (i.e. not a primitive type such as int), because only reference types may be used as type parameters in generics (and T is a type parameter).

So, if you pass int[], you get T = int[], and you code doesn't work as expected. But if you pass array of reference type (for example, Integer[]), you get T = Integer and everything works:

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] + " "); 
} 
烟燃烟灭 2024-10-05 01:19:38

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

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

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

在原始数组上使用 Arrays.asList 会导致 asListint[] 视为单个对象而不是数组。它返回 List 而不是 List。因此,您基本上是在对单个元素 List 进行洗牌,因此没有任何内容真正被洗牌。

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

Try adding this line of code to your test:

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

You will see you are printing out a single element List.

Using Arrays.asList on a primitive array cause asList to treat the int[] as a single object rather than an array. It returns a List<int[]> instead of a List<Integer>. So, you are basically shuffling a single element List and so nothing really gets shuffled.

Notice that some of the answers already given are wrong because asList returns a List backed by the original array, nothing gets copied - all changes are reflected in the orginal array.

可是我不能没有你 2024-10-05 01:19:38

这是行不通的,因为对 shuffle 的调用是在 Arrays.asList 返回的 List 上操作的,而不是在底层数组上操作的。因此,当您迭代数组以打印出值时,没有任何变化。您想要做的是保存对 Arrays.asList 返回的 List 的引用,然后打印出该 List 的值(而不是比数组的值)在随机播放之后。

That doesn't work because the call to shuffle is operating on the List returned by Arrays.asList, not on the underlying array. Thus, when you iterate over the array to print out the values, nothing has changed. What you want to do is save a reference to the List returned by Arrays.asList, and then print out the values of that List (rather than the values of the array) after you shuffle it.

贪了杯 2024-10-05 01:19:38

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

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

Store the list resturned by Arrays.asList and shuffle that...

List myShuffledList = Arrays.asList(arr);
Collections.shuffle(myShuffledList);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文