How to use mutable collections in Scala
Solution 1
For both immutable and mutable collections, :+
and +:
create new collections. If you want mutable collections that automatically grow, use the +=
and +=:
methods defined by collection.mutable.Buffer
.
Similarly, map
returns a new collection — look for transform
to change the collection in place.
Solution 2
map
operation applies the given function to all the elements of collection, and produces a new collection.
The operation you are looking for is called transform
. You can think of it as an in-place map
except that the transformation function has to be of type a -> a
instead of a -> b
.
scala> import collection.mutable.Buffer
import collection.mutable.Buffer
scala> Buffer(6, 3, 90)
res1: scala.collection.mutable.Buffer[Int] = ArrayBuffer(6, 3, 90)
scala> res1 transform { 2 * }
res2: res1.type = ArrayBuffer(12, 6, 180)
scala> res1
res3: scala.collection.mutable.Buffer[Int] = ArrayBuffer(12, 6, 180)
Solution 3
The map
method never modifies the collection on which you call it. The type system wouldn't allow such an in-place map implementation to exist - unless you changed its type signature, so that on some type Collection[A]
you could only map using a function of type A => A
.
(Edit: as other answers have pointed out, there is such a method called transform
!)
Because map
creates a new collection, you can go from a Collection[A]
to a Collection[B]
using a function A => B
, which is much more useful.
Henry Henrinson
Updated on May 15, 2020Comments
-
Henry Henrinson about 4 years
I think I may be failing to understand how mutable collections work. I would expect mutable collections to be affected by applying map to them or adding new elements, however:
scala> val s: collection.mutable.Seq[Int] = collection.mutable.Seq(1) s: scala.collection.mutable.Seq[Int] = ArrayBuffer(1) scala> s :+ 2 //appended an element res32: scala.collection.mutable.Seq[Int] = ArrayBuffer(1, 2) scala> s //the original collection is unchanged res33: scala.collection.mutable.Seq[Int] = ArrayBuffer(1) scala> s.map(_.toString) //mapped a function to it res34: scala.collection.mutable.Seq[java.lang.String] = ArrayBuffer(1) scala> s //original is unchanged res35: scala.collection.mutable.Seq[Int] = ArrayBuffer(1) //maybe mapping a function that changes the type of the collection shouldn't work //try Int => Int scala> s.map(_ + 1) res36: scala.collection.mutable.Seq[Int] = ArrayBuffer(2) scala> s //original unchanged res37: scala.collection.mutable.Seq[Int] = ArrayBuffer(1)
This behaviour doesn't seem to be separate from the immutable collections, so when do they behave separately?