Java 为什么我的数组的 Collections.shuffle() 失败?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3981420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does Collections.shuffle() fail for my array?
提问by Dmitry
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.
结果是:0 1 2 3 4 5 6 7 8 9。
I was expecting a randomly shuffled sequence.
我期待一个随机洗牌的序列。
采纳答案by axtavt
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 Integer
s. Therefore you shuffle a newly created list of int[]
.
Arrays.asList()
不能像您期望的那样应用于原始类型的数组。应用于 时int[]
,Arrays.asList()
生成int[]
s 列表而不是Integer
s列表。因此,您将新创建的int[]
.
This is a subtle behaviour of variadic arguments and generics in Java. Arrays.asList()
is declared as
这是 Java 中可变参数和泛型的微妙行为。Arrays.asList()
被声明为
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).
因此,它可以采用某种类型的多个参数T
并生成一个包含这些参数的列表,或者它可以采用一个类型的参数T[]
并返回由该数组支持的列表(这就是可变参数的工作方式)。
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).
但是,后一个选项仅在T
是引用类型(即不是诸如 之类的原始类型int
)时才有效,因为只有引用类型可以用作泛型T
中的类型参数(并且是类型参数)。
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:
因此,如果您通过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] + " ");
}
回答by Nate W.
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.
这不起作用,因为对 的调用shuffle
是对List
返回的 by 进行操作Arrays.asList
,而不是对底层数组进行操作。因此,当您遍历数组以打印出值时,没有任何变化。你想要做的是保存对List
返回的引用Arrays.asList
,然后List
在你之后打印出它的值(而不是数组的值)shuffle
。
回答by mmccomb
Store the list resturned by Arrays.asList and shuffle that...
存储由 Arrays.asList 返回的列表并洗牌...
List myShuffledList = Arrays.asList(arr);
Collections.shuffle(myShuffledList);
回答by MAK
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
.
您将看到您正在打印单个元素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.
使用Arrays.asList
上基本数组原因asList
治疗int[]
作为单个对象,而不是阵列。它返回 aList<int[]>
而不是 a List<Integer>
。所以,你基本上List
是在打乱单个元素,所以没有真正被打乱。
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.
请注意,已经给出的一些答案是错误的,因为asList
返回由原始数组支持的 List,没有任何内容被复制 - 所有更改都反映在原始数组中。