我正在寻找将collection.mutable.Seq[T]
转换为collection.immutable.Seq[T]
的最佳方式。
答案 0 :(得分:39)
如果您想将ListBuffer
转换为List
,请使用.toList
。我之所以提到这一点是因为特定转换是在恒定时间内执行的。但请注意,ListBuffer
的任何进一步使用都将导致首先复制其内容。
否则,你可以做collection.immutable.Seq(xs: _*)
,假设xs是可变的,因为你不可能以任何其他方式获得更好的性能。
答案 1 :(得分:15)
按照规定:
def convert[T](sq: collection.mutable.Seq[T]): collection.immutable.Seq[T] =
collection.immutable.Seq[T](sq:_*)
<强>加成强>
本机方法使用起来有点棘手。它们已在scala.collection.Seq
上定义,您必须仔细查看是否返回collection.immutable
或collection.mutable
。例如.toSeq
返回collection.Seq
,但不保证可变性。但是,.toIndexedSeq
会返回collection.immutable.IndexedSeq
,因此使用似乎没问题。我不确定,如果这确实是预期的行为,因为还有一个collection.mutable.IndexedSeq
。
最安全的方法是将其手动转换为预期的集合,如上所示。使用本机转换时,我认为最佳做法是添加包含(mutable
/ immutable
)的类型注释,以确保返回正确的集合。
答案 2 :(得分:6)
toList
, toStream
(或LinearSeq
如果你想要它是懒惰的)是首选方式,因为你可以确定你得到的是不可变的(因为List和流是)。如果你想要一个不可变的toVector
,那就没有IndexedSeq
方法了,但似乎toIndexedSeq
给你一个Vector(它是不可变的),如果不是所有的话那么。
另一种方法是使用breakOut
。这将查看您在返回类型中的目标类型,如果可能,请您。 e.g。
scala> val ms = collection.mutable.Seq(1,2,3)
ms: scala.collection.mutable.Seq[Int] = ArrayBuffer(1, 2, 3)
scala> val r: List[Int] = ms.map(identity)(collection.breakOut)
r: List[Int] = List(1, 2, 3)
scala> val r: collection.immutable.Seq[Int] = ms.map(identity)(collection.breakOut)
r: scala.collection.immutable.Seq[Int] = Vector(1, 2, 3)
有关此类黑魔法的更多信息,请获取一些浓咖啡,然后查看this question。
答案 3 :(得分:2)
如果您还使用Set
和Map
,也可以使用TreeSet
作为示例进行尝试。
import scala.collection.mutable
val immutableSet = TreeSet(blue, green, red, yellow)
//converting a immutable set to a mutable set
val mutableSet = mutable.Set.empty ++= immutableSet
//converting a mutable set back to immutable set
val anotherImmutableSet = Set.empty ++ mutableSet
以上示例来自Scala编程