【问题标题】:Converting mutable collection to immutable将可变集合转换为不可变集合
【发布时间】:2012-01-19 08:42:16
【问题描述】:

我正在寻找将collection.mutable.Seq[T] 转换为collection.immutable.Seq[T] 的最佳方法。

【问题讨论】:

    标签: scala collections


    【解决方案1】:

    如果您还使用SetMap,您也可以尝试这些,以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 编程》一书

    【讨论】:

      【解决方案2】:

      如果要将ListBuffer 转换为List,请使用.toList。我提到这一点是因为特定的转换是在恒定时间内执行的。但请注意,进一步使用 ListBuffer 将导致其内容首先被复制。

      否则,您可以使用collection.immutable.Seq(xs: _*),假设 xs 是可变的,因为您不太可能以任何其他方式获得更好的性能。

      【讨论】:

      • 这似乎不起作用 - 我最终得到一个带有一个元素的不可变序列(可变序列)。愚蠢的斯卡拉。
      【解决方案3】:

      toList(或者toStream,如果你想要一个LinearSeq)是首选的方式,因为你可以确定你得到的东西是不可变的(因为List和Stream是)。如果您想要一个不可变的IndexedSeq,则没有toVector 方法,但似乎toIndexedSeq 为您提供了一个Vector(它是不可变的),如果不是所有时间的话。

      另一种方法是使用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)
      

      有关这种黑魔法的更多信息,请喝点浓咖啡并查看this question

      【讨论】:

        【解决方案4】:

        如指定:

        def convert[T](sq: collection.mutable.Seq[T]): collection.immutable.Seq[T] = 
          collection.immutable.Seq[T](sq:_*)
        

        加法

        本机方法使用起来有点棘手。它们已在scala.collection.Seq 上定义,您必须仔细查看它们是否返回collection.immutablecollection.mutable。例如.toSeq 返回一个collection.Seq,它不保证可变性。 .toIndexedSeq 然而,返回一个 collection.immutable.IndexedSeq 所以它似乎很好用。不过,我不确定这是否真的是预期的行为,因为还有一个 collection.mutable.IndexedSeq

        最安全的方法是手动将其转换为预期的集合,如上所示。在使用原生转换时,我认为最好添加类型注释,包括 (mutable/immutable) 以确保返回正确的集合。

        【讨论】:

        • 不错。但是像 .toIndexedSeq.toStream 这样的原生方法呢?我只是不确定哪个是最佳解决方案。
        猜你喜欢
        • 2011-03-11
        • 1970-01-01
        • 1970-01-01
        • 2021-08-20
        • 1970-01-01
        • 2012-02-12
        • 2021-01-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多