scala 将可变集合转换为不可变集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8489829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting mutable collection to immutable
提问by Nikita Volkov
I'm looking for a best way of converting a collection.mutable.Seq[T]to collection.immutable.Seq[T].
我正在寻找将 a 转换collection.mutable.Seq[T]为collection.immutable.Seq[T].
回答by Daniel C. Sobral
If you want to convert ListBufferinto a List, use .toList. I mention this because that particular conversion is performed in constant time. Note, though, that any further use of the ListBufferwill result in its contents being copied first.
如果要转换ListBuffer为List,请使用.toList. 我提到这一点是因为该特定转换是在恒定时间内执行的。但是请注意,任何进一步使用ListBuffer将导致其内容首先被复制。
Otherwise, you can do collection.immutable.Seq(xs: _*), assuming xs is mutable, as you are unlikely to get better performance any other way.
否则,您可以这样做collection.immutable.Seq(xs: _*),假设 xs 是可变的,因为您不太可能以任何其他方式获得更好的性能。
回答by Debilski
As specified:
作为指定:
def convert[T](sq: collection.mutable.Seq[T]): collection.immutable.Seq[T] =
collection.immutable.Seq[T](sq:_*)
Addition
添加
The native methods are a little tricky to use. They are already defined on scala.collection.Seqand you'll have to take a close look whether they return a collection.immutableor a collection.mutable. For example .toSeqreturns a collection.Seqwhich makes no guarantees about mutability. .toIndexedSeqhowever, returns a collection.immutable.IndexedSeqso it seems to be fine to use. I'm not sure though, if this is really the intended behaviour as there is also a collection.mutable.IndexedSeq.
本机方法使用起来有点棘手。它们已经在 on 上定义scala.collection.Seq,您必须仔细查看它们是否返回 acollection.immutable或 a collection.mutable。例如,.toSeq返回collection.Seq不保证可变性的 a 。.toIndexedSeq但是,返回 acollection.immutable.IndexedSeq因此似乎可以使用。不过,我不确定这是否真的是预期的行为,因为还有一个collection.mutable.IndexedSeq.
The safest approach would be to convert it manually to the intended collection as shown above. When using a native conversion, I think it is best practice to add a type annotation including (mutable/immutable) to ensure the correct collection is returned.
最安全的方法是手动将其转换为预期的集合,如上所示。使用本机转换时,我认为最佳做法是添加包括 ( mutable/ immutable)的类型注释以确保返回正确的集合。
回答by Luigi Plinge
toList(or toStreamif you want it lazy) are the preferred way if you want a LinearSeq, as you can be sure what you get back is immutable (because List and Stream are). There's no toVectormethod if you want an immutable IndexedSeq, but it seems that toIndexedSeqgives you a Vector (which is immutable) most if not all of the time.
toList(或者toStream如果你想要它懒惰)如果你想要 a 是首选方式LinearSeq,因为你可以确定你得到的东西是不可变的(因为 List 和 Stream 是)。toVector如果您想要一个 immutable IndexedSeq,则没有任何方法,但似乎toIndexedSeq大多数情况下都可以为您提供一个 Vector (它是不可变的)。
Another way is to use breakOut. This will look at the type you're aiming for in your return type, and if possible oblige you. e.g.
另一种方法是使用breakOut. 这将查看您在返回类型中的目标类型,并在可能的情况下帮助您。例如
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)
For more info on such black magic, get some strong coffee and see this question.
有关此类黑魔法的更多信息,请喝杯浓咖啡并查看此问题。
回答by Wang Sheng
If you are also working with Setand Mapyou can also try these, using TreeSetas an example.
如果您也正在使用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
The above example is from book Programming in Scala
上面的例子来自于 Scala 编程

