83
private[this]object MMMap extends  HashMap[A, Set[B]] with MultiMap[A, B]

How convert it to immutable?

Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
Jeriho
  • 7,129
  • 9
  • 41
  • 57

4 Answers4

76

The immutable hierarchy doesn't contain a MultiMap, so you won't be able to use the converted structure with the same convenient syntax. But if you're happy to deal with key/valueset pairs, then:

If you just want a mutable HashMap, you can just use x.toMap in 2.8 or collection.immutable.Map(x.toList: _*) in 2.7.

But if you want the whole structure to be immutable--including the underlying set!--then you have to do more: you need to convert the sets along the way. In 2.8:

x.map(kv => (kv._1,kv._2.toSet)).toMap

In 2.7:

collection.immutable.Map(
  x.map(kv => (kv._1,collection.immutable.Set(kv._2.toList: _*))).toList: _*
)
Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
34
scala> val mutableMap = new HashMap[Int, String]
mutableMap: scala.collection.mutable.HashMap[Int,String] = Map()

scala> mutableMap += 1 -> "a"
res5: mutableMap.type = Map((1,a))

scala> mutableMap
res6: scala.collection.mutable.HashMap[Int,String] = Map((1,a))

scala> val immutableMap = mutableMap.toMap
immutableMap: scala.collection.immutable.Map[Int,String] = Map((1,a))

scala> immutableMap += 2 -> "b"
<console>:11: error: reassignment to val
       immutableMap += 2 -> "b"
                ^
michael.kebe
  • 10,916
  • 3
  • 44
  • 62
  • I was surprised a bit when I saw "mutableMap.toMap" but then I verified api and didn't found nothing resembling. http://www.scala-lang.org/docu/files/api/scala/collection/mutable/HashMap.html Second issue - Set[B] is mutable. That is why converting is not so easy. – Jeriho May 12 '10 at 09:00
  • 4
    @Jeriho: toMap is introduced in Scala2.8 – Eastsun May 12 '10 at 09:07
  • Thx Eastsun. Sorry Jeriho, I didn't mentioned it. – michael.kebe May 12 '10 at 09:10
13

You can use myMap.toMap to convert an a mutable map into immutable in Scala 2.8 and later versions.

Looking at definition of toMap from documentation:

def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U] = {
  val b = immutable.Map.newBuilder[T, U]
  for (x <- self) b += x
  b.result
}
Fahad Siddiqui
  • 1,829
  • 1
  • 19
  • 41
12

You can just to the following

val imm_map = MMMap.toMap