我有一个要随机排列的数组。在 Java 中,有一个方法 Collections.shuffle() 可以随机打乱 List 的元素。它也可以在数组上使用:
String[] array = new String[]{"a", "b", "c"};
// Shuffle the array; works because the list returned by Arrays.asList() is backed by the array
Collections.shuffle(Arrays.asList(array));
我尝试在 Scala 数组上使用它,但 Scala 解释器给出了一个冗长的答案:
scala> val a = Array("a", "b", "c")
a: Array[java.lang.String] = Array(a, b, c)
scala> java.util.Collections.shuffle(java.util.Arrays.asList(a))
<console>:6: warning: I'm seeing an array passed into a Java vararg.
I assume that the elements of this array should be passed as individual arguments to the vararg.
Therefore I follow the array with a `: _*', to mark it as a vararg argument.
If that's not what you want, compile this file with option -Xno-varargs-conversion.
java.util.Collections.shuffle(java.util.Arrays.asList(a))
^
<console>:6: error: type mismatch;
found : Array[java.lang.String]
required: Seq[Array[java.lang.String]]
java.util.Collections.shuffle(java.util.Arrays.asList(a))
^
这里到底发生了什么?我不想用特殊标志(-Xno-varargs-conversion)编译我的代码,如果那是解决方案的话,正因为如此。
那么,如何在 Scala 数组上使用 Java 的 Collections.shuffle() 呢?
与此同时,我在 Scala 中编写了自己的 shuffle 方法:
// Fisher-Yates shuffle, see: http://en.wikipedia.org/wiki/Fisher–Yates_shuffle
def shuffle[T](array: Array[T]): Array[T] = {
val rnd = new java.util.Random
for (n <- Iterator.range(array.length - 1, 0, -1)) {
val k = rnd.nextInt(n + 1)
val t = array(k); array(k) = array(n); array(n) = t
}
return array
}
它在适当的位置打乱数组,并为方便起见返回数组本身。