collection.mutable.Seq[T]
をcollection.immutable.Seq[T]
に変換する最良の方法を探しています。
ListBuffer
をList
に変換する場合は、_.toList
_を使用します。その特定の変換一定の時間内に実行されるであるため、これについて言及します。ただし、ListBuffer
をさらに使用すると、その内容が最初にコピーされることに注意してください。
それ以外の場合は、他の方法ではパフォーマンスが向上する可能性が低いため、xsが可変であると想定して、collection.immutable.Seq(xs: _*)
を実行できます。
指定どおり:
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
)を含む型注釈を追加することをお勧めします。
toList
(遅延を希望する場合はtoStream
)がLinearSeq
を希望する場合の推奨される方法です。ストリームは)。不変toVector
が必要な場合はIndexedSeq
メソッドはありませんが、toIndexedSeq
が常に(不変である)Vectorを提供するようです。
もう1つの方法は、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)
そのような黒魔術の詳細については、濃いコーヒーを飲み、 この質問 を参照してください。
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のプログラミング