如何在斯卡拉阵列上使用Java Collections.shuffle()? [英] How to use Java Collections.shuffle() on a Scala array?

查看:139
本文介绍了如何在斯卡拉阵列上使用Java Collections.shuffle()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,我想随机排列替换一个数组。在Java中,有一个方法Collections.shuffle(),可以洗牌列表中的元素随机。它可以在阵列上使用太

  String []数组=新的String [] {A,B,C};//洗牌数组;由于工作)由Arrays.asList(返回的列表是由数组支持
Collections.shuffle(Arrays.asList(阵列));

我尝试了斯卡拉阵列上使用这一点,但斯卡拉间preTER用冗长的回答,

 斯卡拉> VAL一个=阵列(一,B,C)
答:数组[java.lang.String中] =阵列(A,B,C)斯卡拉> java.util.Collections.shuffle(java.util.Arrays.asList(a))的
<&控制台GT; 6:警告:我看到传递到一个Java可变参数的数组。
我认为这个数组的元素应该作为单独的参数可变参数进行传递。
因此,我遵循了`数组:_ *,将其标记为一个可变参数的参数。
如果这不是你想要的,编译选项-Xno-可变参数转换文件。
       java.util.Collections.shuffle(java.util.Arrays.asList(a))的
                                                             ^
<&控制台GT; 6:错误:类型不匹配;
 发现:数组[java.lang.String中]
 要求:序号[数组[java.lang.String中]
       java.util.Collections.shuffle(java.util.Arrays.asList(a))的
                                                             ^

究竟是怎么回事?我不希望我的编译code具有特殊标志(-Xno-可变参数转换),如果是这样的解决方案可言,只是因为这一点。

所以,我怎么斯卡拉阵列上使用Java的Collections.shuffle()?

我写我自己的方法洗牌斯卡拉其间:

  //费雪耶茨洗牌,请参阅:http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
高清洗牌[T](数组:数组[T]):数组[T] = {
VAL RND =新java.util.Random中
为(N下; - Iterator.range(array.length - 1,0,-1)){
VAL K = rnd.nextInt第(n + 1)
VAL T =阵列(K);阵列(k)的=阵列(n)的;阵列(N)= T
}
返回的数组
}

据洗牌到位数组,并返回数组本身的方便。


解决方案

  java.util.Collections.shuffle(java.util.Arrays.asList(A:_ *))

对于上面的正常工作,一的元素类型必须是scala.AnyRef(相当于java.lang.Object)中的一个子类,因为Arrays.asList()使用传入的后备存储结果的Java数组.util.List和java.util.List中只能包含对象引用(而不是原始值)。*

这也是为什么Collections.shuffle(),它慢腾腾传入的java.util.List的实际洗牌数组。*

*:请参见下面

的说明

例如:

 斯卡拉> VAL A =数组[java.lang.Integer中的(1,2,3)//注意类型参数
答:数组[java.lang.Integer中] =阵列(1,2,3)斯卡拉> java.util.Collections.shuffle(java.util.Arrays.asList(A:_ *))斯卡拉>一个
res43:数组[java.lang.Integer中] =阵列(1,3,2)斯卡拉> java.util.Collections.shuffle(java.util.Arrays.asList(A:_ *))斯卡拉>一个
res45:数组[java.lang.Integer中] =阵列(1,2,3)

请注意:斯卡拉2.7.5用于上述code片段。斯卡拉2.8.0表现为丹尼尔展示不同的行为。为了安全起见,不依赖于一个事实,即数组被打乱,而是一个从Arrays.asList()返回被洗牌的列表中。

 斯卡拉> VAL一个=数组[java.lang.Integer中](1,2,3)
答:数组[java.lang.Integer中] =阵列(1,2,3)斯卡拉> VAL B = java.util.Arrays.asList(A:_ *)
A:java.util.List的[java.lang.Integer中] = [1,2,3]斯卡拉> java.util.Collections.shuffle(二)斯卡拉> b
res50:java.util.List的[java.lang.Integer中] = [2,1,3]斯卡拉> java.util.Collections.shuffle(二)斯卡拉> b
res52:java.util.List的[java.lang.Integer中] = [3,1,2]

I have an array that I want to permutate randomly. In Java, there is a method Collections.shuffle() that can shuffle the elements of a List randomly. It can be used on an array too:

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));

I tried using this on a Scala array, but the Scala interpreter responds with a lengthy answer:

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))
                                                             ^

What exactly is happening here? I don't want to compile my code with a special flag (-Xno-varargs-conversion), if that is the solution at all, just because of this.

So, how do I use Java's Collections.shuffle() on a Scala array?

I wrote my own shuffle method in Scala in the meantime:

// 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
}

It shuffles the array in place, and returns the array itself for convenience.

解决方案

java.util.Collections.shuffle(java.util.Arrays.asList(a:_*))

For the above to work correctly, a's element type has to be a subclass of scala.AnyRef (equivalent to java.lang.Object) because Arrays.asList() uses the array passed in as the backing store for the result java.util.List and java.util.List can contain only object references (not primitive values).*

That is also the reason why Collections.shuffle() which shuffles the passed-in java.util.List actually shuffled the array.*

*: See the note below

For example:

scala> val a = Array[java.lang.Integer](1, 2, 3) // note the type parameter                  
a: Array[java.lang.Integer] = Array(1, 2, 3)

scala> java.util.Collections.shuffle(java.util.Arrays.asList(a:_*))

scala> a
res43: Array[java.lang.Integer] = Array(1, 3, 2)

scala> java.util.Collections.shuffle(java.util.Arrays.asList(a:_*))

scala> a
res45: Array[java.lang.Integer] = Array(1, 2, 3)

Note: Scala 2.7.5 is used for the above code snippets. Scala 2.8.0 exhibits different behaviors as Daniel demonstrated. To be on the safe side, do not depend on the fact that the array gets shuffled but instead the list that is returned from Arrays.asList() gets shuffled.

scala> val a = Array[java.lang.Integer](1, 2, 3)
a: Array[java.lang.Integer] = Array(1, 2, 3)

scala> val b = java.util.Arrays.asList(a:_*)
b: java.util.List[java.lang.Integer] = [1, 2, 3]

scala> java.util.Collections.shuffle(b)

scala> b
res50: java.util.List[java.lang.Integer] = [2, 1, 3]

scala> java.util.Collections.shuffle(b)

scala> b
res52: java.util.List[java.lang.Integer] = [3, 1, 2]

这篇关于如何在斯卡拉阵列上使用Java Collections.shuffle()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆