[英]Why does List<Object[]> needs explicit casting to convert into Scala collection?
Say I have the following Java collection: 说我有以下Java集合:
public static List<Object[]> javaStuff = new ArrayList<Object[]>();
And that, from Scala, I want to refer to that collection, convert it Scala collection and return an Iterator[]
over it. 而且,我想从Scala中引用该集合,将其转换为Scala集合,然后在其上返回Iterator[]
。
Can anyone explain to me why the following (toy) code does not compile? 谁能向我解释为什么以下(玩具)代码无法编译?
def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
import scala.collection.JavaConverters._
val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala // This does not compile!
r.iterator
}
More specifically, the error IntelliJ highlights is: 更具体地说,IntelliJ突出显示的错误是:
Expression of type Buffer[Array[AnyRef]] does not conform to expected type Buffer[Array[AnyRef]]
...which was quite uninformative. ...这是毫无根据的 Trying to run the code, the error is a bit more helpful: 尝试运行代码时,该错误会有所帮助:
Error:(18, 58) type mismatch;
found : scala.collection.mutable.Buffer[scala.Array[Object]]
required: scala.collection.mutable.Buffer[Array[AnyRef]]
val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala
^
At which point, I changed the original code into: 在这一点上,我将原始代码更改为:
def convertMethod[Array[AnyRef]]() : Iterator[Array[AnyRef]] = {
import scala.collection.JavaConverters._
val r: mutable.Buffer[Array[AnyRef]] = MyTestClass.javaStuff.asScala.map(_.asInstanceOf[Array[AnyRef]])
r.iterator
}
...and it worked! ...而且有效!
Now my question really is: why is this necessary? 现在我的问题确实是:为什么这是必要的? Is there a way to avoid that explicit casting? 有没有一种方法可以避免这种显式转换?
The reason is simple. 原因很简单。 In convertMethod
, Array
is a type parameter and thus does not refer to scala.Array
at all. 在convertMethod
, Array
是类型参数,因此根本不引用scala.Array
。
You should change this: 您应该更改此:
def convertMethod[Array[AnyRef]]()
to this: 对此:
def convertMethod()
Note that contrary to what shadowlands said in a comment, scala.Array
really is the same thing as a java array (except for the fact that scala arrays are not covariant, but it does not come into play here). 请注意,与scala.Array
在评论中所说的相反, scala.Array
实际上与java数组是一样的(除了scala数组不是协变的,但它不在这里起作用)。
Change 更改
def convertMethod[Array[AnyRef]]() =
to 至
def convertMethod() =
The first one creates a method that takes a type parameter with name Array
, which by itself takes a type parameter of name AnyRef
(ie a higher kinded type). 第一个创建一个方法,该方法采用名称为Array
的类型参数,该方法本身采用名称为AnyRef
的类型参数(即,更高种类的类型)。 These newly introduced names hide the built in types Array
and AnyRef
. 这些新引入的名称隐藏了内置类型Array
和AnyRef
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.