如何将java 1.4 Collection转换为Scala Seq?
我正在尝试将java集合传递给scala方法:
import scala.collection.JavaConversions._
// list is a 1.4 java.util.ArrayList
// repository.getDir is Java legacy code
val list = repository.getDir(...)
perform(list)
def perform(entries: List[SVNDirEntry]) = ...
我总是收到这个错误:
type mismatch; found : java.util.Collection[?0] where type ?0 required: List
[SVNDirEntry]
所以我想我必须自己创建参数化序列,因为Scala只能创建一个非参数化的Iterable?
答案 0 :(得分:3)
首先,您必须确保list
的类型为java.util.List[SVNDirEntry]
。为此,请使用强制转换:
list.asInstanceOf[java.util.List[SVNDirEntry]]
之后,如果导入JavaConversions
对象,将为您解析隐式转换。 JavaConversions
对象中存在对Scala序列的隐式转换。请参阅以下示例,其中包含传递给需要Scala序列的方法的字符串列表:
scala> val jvlist: java.util.List[_] = new java.util.ArrayList[String]
jvlist: java.util.List[_] = []
scala> jvlist.asInstanceOf[java.util.List[String]]
res0: java.util.List[String] = []
scala> import collection.JavaConversions._
import collection.JavaConversions._
scala> def perform(scalaseq: Seq[String]) = println("ok")
perform: (scalaseq: scala.collection.Seq[String])Unit
scala> perform(res0)
ok
这些转换不会复制元素 - 它们只是构建Java集合的包装器。两个版本都指向相同的基础数据。因此,JavaConversions
中没有可变Java列表中的不可变Scala列表的隐式转换,因为这样可以更改保证不可变的Scala集合的内容。
简而言之 - 如果您可以使用不太具体的界面(例如上面的Seq[...]
),则在为方法定义参数时更喜欢List[...]
到perform
。或者编写自己的函数,通过复制元素来进行转换。
答案 1 :(得分:2)
您必须将旧版集合转换为目标类型。有点像:
perform(list.asInstanceOf[List[SVNDirEntry]])