Je recherche un meilleur moyen de convertir un collection.mutable.Seq[T]
à collection.immutable.Seq[T]
.
Si vous souhaitez convertir ListBuffer
en List
, utilisez .toList
. Je mentionne cela parce que cette conversion particulière est effectuée en temps constant. Notez cependant que toute utilisation ultérieure de ListBuffer
entraînera la copie de son contenu en premier.
Sinon, vous pouvez faire collection.immutable.Seq(xs: _*)
, en supposant que xs est modifiable, car il est peu probable que vous obteniez de meilleures performances d'une autre manière.
Comme spécifié:
def convert[T](sq: collection.mutable.Seq[T]): collection.immutable.Seq[T] =
collection.immutable.Seq[T](sq:_*)
Ajout
Les méthodes natives sont un peu délicates à utiliser. Ils sont déjà définis sur scala.collection.Seq
et vous devrez regarder de plus près s'ils renvoient un collection.immutable
ou un collection.mutable
. Par exemple .toSeq
renvoie un collection.Seq
qui ne garantit pas la mutabilité. .toIndexedSeq
cependant, renvoie un collection.immutable.IndexedSeq
donc il semble être bon à utiliser. Je ne suis pas sûr cependant, si c'est vraiment le comportement prévu car il y a aussi un collection.mutable.IndexedSeq
.
L'approche la plus sûre serait de la convertir manuellement dans la collection prévue, comme indiqué ci-dessus. Lorsque vous utilisez une conversion native, je pense qu'il est préférable d'ajouter une annotation de type comprenant (mutable
/immutable
) pour garantir que la collection correcte est renvoyée.
toList
(ou toStream
si vous le voulez paresseux) sont le moyen préféré si vous voulez un LinearSeq
, car vous pouvez être sûr que ce que vous obtenez est immuable (car List et Stream sont). Il n'y a pas de méthode toVector
si vous voulez une IndexedSeq
immuable, mais il semble que toIndexedSeq
vous donne un vecteur (qui est immuable) la plupart du temps, sinon tout le temps.
Une autre façon consiste à utiliser breakOut
. Cela examinera le type que vous visez dans votre type de retour et, si possible, vous obligera. par exemple.
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)
Pour plus d'informations sur une telle magie noire, prenez du café fort et voyez cette question .
Si vous travaillez également avec Set
et Map
, vous pouvez également les essayer, en utilisant TreeSet
comme exemple.
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
L'exemple ci-dessus provient du livre Programming in Scala