将未参数化的Java 1.4 Collection转换为参数化的Scala序列

时间:2010-10-20 10:20:59

标签: scala scala-2.8

如何将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?

2 个答案:

答案 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]])