问题
LinkedHashMap is used to preserve insertion order in the map, but this only works for mutable maps. Which is the immutable Map implementation that preserves insertion order?
回答1:
ListMap implements an immutable map using a list-based data structure, and thus preserves insertion order.
scala> import collection.immutable.ListMap
import collection.immutable.ListMap
scala> ListMap(1 -> 2) + (3 -> 4)
res31: scala.collection.immutable.ListMap[Int,Int] = Map(1 -> 2, 3 -> 4)
scala> res31 + (6 -> 9)
res32: scala.collection.immutable.ListMap[Int,Int] = Map(1 -> 2, 3 -> 4, 6 -> 9)
The following extension method - Seq#toListMap can be quite useful when working with ListMaps.
scala> import scalaz._, Scalaz._, Liskov._
import scalaz._
import Scalaz._
import Liskov._
scala> :paste
// Entering paste mode (ctrl-D to finish)
implicit def seqW[A](xs: Seq[A]) = new SeqW(xs)
class SeqW[A](xs: Seq[A]) {
def toListMap[B, C](implicit ev: A <~< (B, C)): ListMap[B, C] = {
ListMap(co[Seq, A, (B, C)](ev)(xs) : _*)
}
}
// Exiting paste mode, now interpreting.
seqW: [A](xs: Seq[A])SeqW[A]
defined class SeqW
scala> Seq((2, 4), (11, 89)).toListMap
res33: scala.collection.immutable.ListMap[Int,Int] = Map(2 -> 4, 11 -> 89)
回答2:
While ListMap will preserve insertion order, it is not very efficient - e.g. lookup time is linear. I suggest you create a new collection class which wraps both the immutable.HashMap and the immutable.TreeMap. The immutable map should be parametrized as immutable.HashMap[Key, (Value, Long)], where the Long in the tuple gives you the pointer to the corresponding entry in the TreeMap[Long, Key]. You then keep an entry counter on the side. This tree map will sort the entries according to the insertion order.
You implement insertion and lookup in the straightforward way - increment the counter, insert into the hash map and insert to the the counter-key pair into the treemap. You use the hash map for the lookup.
You implement iteration by using the tree map.
To implement remove, you have to remove the key-value pair from the hash map and use the index from the tuple to remove the corresponding entry from the tree map.
来源:https://stackoverflow.com/questions/9313866/immutable-scala-map-implementation-that-preserves-insertion-order