Reputation: 1301
Frequently, I find myself implementing methods that build a map from an input source. In this case, I use a scala.collection.mutable.Map
, assuming greater speed and efficiency; however, once this collection is built, I no longer want it to be mutable.
What is the preferred Scala way of returning an immutable map from a mutable one? Usually, I do a myMap.toMap
which obviously works, but smells. Alternatively, you can set the return type to scala.collection.Map
which doesn't require building a new collection, but seems like it could confuse readers.
Thanks for any replies.
Upvotes: 3
Views: 319
Reputation: 345
import scala.collection._
import scala.collection.JavaConversions._
val myMap: mutable.Map[K,V] = ???
val unmodifiable: mutable.Map[K,V] =
java.util.Collections.unmodifiableMap[K,V](myMap)
val newMap = unmodifiable.asInstanceOf[scala.collection.Map[K,V]]
You can cast newMap
to a mutable.Map
, but modifications will throw UnsupportedOperationException
.
In my case, the maps may be small enough that toMap
may be faster and use less memory.
Upvotes: 0
Reputation: 167891
I'm not sure why you think .toMap
smells, but if you want to be explicit collection.immutable.Map() ++ myMap
ought to clearly document what is going on. (Don't forget the ()
; they're not optional.)
Simply changing the return type doesn't fully fix the immutability problem; the mutating methods are no longer visible, but the user could easily cast back. That is the highest performance approach, though, since nothing is really changing.
Upvotes: 5
Reputation: 52681
The best way is to call .toMap
. It's short, clean, and is an explicit way of saying that you want to convert your collection to an immutable.Map
.
I think setting the type to scala.collection.Map
would, indeed, be confusing. It also wouldn't protect you from someone setting the type back. Making the type immutable.Map
is clear and safe.
Upvotes: 7