为什么 List<Object[]> 需要显式转换才能转换为 Scala 集合?
Why does List<Object[]> needs explicit casting to convert into Scala collection?
假设我有以下 Java 集合:
public static List<Object[]> javaStuff = new ArrayList<Object[]>();
而且,从 Scala 中,我想引用该集合,将其转换为 Scala 集合,然后 return 一个 Iterator[]
覆盖它。
任何人都可以向我解释为什么以下(玩具)代码无法编译吗?
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
}
更具体地说,IntelliJ 突出显示的错误是:
Expression of type Buffer[Array[AnyRef]] does not conform to expected type Buffer[Array[AnyRef]]
...信息量不大。尝试运行代码,报错有点帮助:
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
^
此时,我把原来的代码改成了:
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
}
...成功了!
现在我的问题是:为什么这是必要的?有没有办法避免这种显式转换?
改变
def convertMethod[Array[AnyRef]]() =
至
def convertMethod() =
第一个创建了一个方法,它接受一个名为 Array
的类型参数,它本身接受一个名为 AnyRef
的类型参数(即更高类型)。这些新引入的名称隐藏了内置类型 Array
和 AnyRef
.
原因很简单。在 convertMethod
中,Array
是一个类型参数,因此 而不是 指的是 scala.Array
。
你应该改变这个:
def convertMethod[Array[AnyRef]]()
对此:
def convertMethod()
请注意,与 shadowlands 在评论中所说的相反,scala.Array
实际上与 java 数组相同(除了 scala 数组不是协变的,但它不是在这里发挥作用)。
假设我有以下 Java 集合:
public static List<Object[]> javaStuff = new ArrayList<Object[]>();
而且,从 Scala 中,我想引用该集合,将其转换为 Scala 集合,然后 return 一个 Iterator[]
覆盖它。
任何人都可以向我解释为什么以下(玩具)代码无法编译吗?
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
}
更具体地说,IntelliJ 突出显示的错误是:
Expression of type Buffer[Array[AnyRef]] does not conform to expected type Buffer[Array[AnyRef]]
...信息量不大。尝试运行代码,报错有点帮助:
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
^
此时,我把原来的代码改成了:
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
}
...成功了!
现在我的问题是:为什么这是必要的?有没有办法避免这种显式转换?
改变
def convertMethod[Array[AnyRef]]() =
至
def convertMethod() =
第一个创建了一个方法,它接受一个名为 Array
的类型参数,它本身接受一个名为 AnyRef
的类型参数(即更高类型)。这些新引入的名称隐藏了内置类型 Array
和 AnyRef
.
原因很简单。在 convertMethod
中,Array
是一个类型参数,因此 而不是 指的是 scala.Array
。
你应该改变这个:
def convertMethod[Array[AnyRef]]()
对此:
def convertMethod()
请注意,与 shadowlands 在评论中所说的相反,scala.Array
实际上与 java 数组相同(除了 scala 数组不是协变的,但它不是在这里发挥作用)。