I'm looking for a best way of converting a collection.mutable.Seq[T]
to collection.immutable.Seq[T]
.

- 42,792
- 11
- 94
- 169
4 Answers
If you want to convert ListBuffer
into a List
, use .toList
. I mention this because that particular conversion is performed in constant time. Note, though, that any further use of the ListBuffer
will result in its contents being copied first.
Otherwise, you can do collection.immutable.Seq(xs: _*)
, assuming xs is mutable, as you are unlikely to get better performance any other way.

- 42,792
- 11
- 94
- 169

- 295,120
- 86
- 501
- 681
-
1This doesn't seem to work - I end up with an immutable sequence with one element (the mutable sequence). Silly Scala. – cbmanica May 14 '14 at 23:52
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.Seq
and you’ll have to take a close look whether they return a collection.immutable
or a collection.mutable
. For example .toSeq
returns a collection.Seq
which makes no guarantees about mutability. .toIndexedSeq
however, returns a collection.immutable.IndexedSeq
so 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
.
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.

- 66,976
- 12
- 110
- 133
-
Nice. But what about native methods like `.toIndexedSeq` or `.toStream`? I'm just not sure which is a best solution. – Nikita Volkov Dec 13 '11 at 14:04
toList
(or toStream
if 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 toVector
method if you want an immutable IndexedSeq
, but it seems that toIndexedSeq
gives you a Vector (which is immutable) most if not all of the time.
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.
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.

- 1
- 1

- 50,650
- 20
- 113
- 180
If you are also working with Set
and Map
you can also try these, using TreeSet
as an example.
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

- 780
- 1
- 6
- 18