集合(Scala 2.8 - 2.12)

Java 和 Scala 集合之间的转换

语言

与 Scala 一样,Java 也有一个丰富的集合库。两者之间有很多相似之处。例如,这两个库都知道迭代器、可迭代对象、集合、映射和序列。但也有重要的区别。特别是,Scala 库更强调不可变集合,并提供了更多将集合转换为新集合的操作。

有时您可能需要从一个集合框架传递到另一个集合框架。例如,您可能希望访问现有的 Java 集合,就像访问 Scala 集合一样。或者,您可能希望将 Scala 的集合之一传递给 Java 方法,该方法需要其 Java 对应项。这样做非常容易,因为 Scala 在 JavaConverters 对象中提供了所有主要集合类型之间的隐式转换。特别是,您会发现以下类型之间的双向转换。

Iterator               <=>     java.util.Iterator
Iterator               <=>     java.util.Enumeration
Iterable               <=>     java.lang.Iterable
Iterable               <=>     java.util.Collection
mutable.Buffer         <=>     java.util.List
mutable.Set            <=>     java.util.Set
mutable.Map            <=>     java.util.Map
mutable.ConcurrentMap  <=>     java.util.concurrent.ConcurrentMap

要启用这些转换,只需从 JavaConverters 对象中导入它们即可

scala> import collection.JavaConverters._
import collection.JavaConverters._

这通过名为 asScalaasJava 的扩展方法启用了 Scala 集合与其对应的 Java 集合之间的转换

scala> import collection.mutable._
import collection.mutable._

scala> val jul: java.util.List[Int] = ArrayBuffer(1, 2, 3).asJava
jul: java.util.List[Int] = [1, 2, 3]

scala> val buf: Seq[Int] = jul.asScala
buf: scala.collection.mutable.Seq[Int] = ArrayBuffer(1, 2, 3)

scala> val m: java.util.Map[String, Int] = HashMap("abc" -> 1, "hello" -> 2).asJava
m: java.util.Map[String,Int] = {abc=1, hello=2}

在内部,这些转换通过设置一个“包装器”对象来工作,该对象将所有操作转发到基础集合对象。因此,在 Java 和 Scala 之间转换时,集合永远不会被复制。一个有趣的属性是,如果你对某种类型(比如 Java 类型)进行往返转换,将其转换为相应的 Scala 类型,然后再转换回相同的 Java 类型,你最终会得到与你开始时相同的集合对象。

某些其他 Scala 集合也可以转换为 Java,但无法转换回原始的 Scala 类型

Seq           =>    java.util.List
mutable.Seq   =>    java.util.List
Set           =>    java.util.Set
Map           =>    java.util.Map

因为 Java 在其类型中不区分可变集合和不可变集合,所以从某种类型(比如 scala.immutable.List)转换会产生一个 java.util.List,其中所有变异操作都会抛出“UnsupportedOperationException”。这是一个示例

scala> val jul = List(1, 2, 3).asJava
jul: java.util.List[Int] = [1, 2, 3]

scala> jul.add(7)
java.lang.UnsupportedOperationException
  at java.util.AbstractList.add(AbstractList.java:148)

此页面的贡献者