web-dev-qa-db-ja.com

可変コレクションを不変に変換する

collection.mutable.Seq[T]collection.immutable.Seq[T]に変換する最良の方法を探しています。

31
Nikita Volkov

ListBufferListに変換する場合は、_.toList_を使用します。その特定の変換一定の時間内に実行されるであるため、これについて言及します。ただし、ListBufferをさらに使用すると、その内容が最初にコピーされることに注意してください。

それ以外の場合は、他の方法ではパフォーマンスが向上する可能性が低いため、xsが可変であると想定して、collection.immutable.Seq(xs: _*)を実行できます。

39

指定どおり:

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

追加

ネイティブメソッドを使用するには少し注意が必要です。それらはすでにscala.collection.Seqで定義されているため、collection.immutableを返すかcollection.mutableを返すかをよく検討する必要があります。たとえば、.toSeqcollection.Seqを返しますが、これは可変性を保証するものではありません。 .toIndexedSeqcollection.immutable.IndexedSeqを返すため、使用しても問題ないようです。ただし、collection.mutable.IndexedSeqもあるため、これが本当に意図された動作であるかどうかはわかりません。

最も安全な方法は、上記のように、目的のコレクションに手動で変換することです。ネイティブ変換を使用する場合、正しいコレクションが返されるようにするために、(mutable/immutable)を含む型注釈を追加することをお勧めします。

15
Debilski

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)

そのような黒魔術の詳細については、濃いコーヒーを飲み、 この質問 を参照してください。

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のプログラミング

3
Wang Sheng