2012-02-16 102 views
36

LinkedHashMap不可改变的Scala Map实现用于在地图保留插入顺序,但这只适用于可变地图。哪一个是不变的Map实现,它保留了插入顺序?,保留插入顺序

+1

这不是一个确切的重复,问题是不可变的映射,涉嫌重复约两个可变和不可变的。另一个问题不*直接*回答不可变的部分(或许是间接的) – 2015-07-21 02:16:49

回答

41

ListMap实现使用基于列表的数据结构的一个不可变的映射,并且因此保留插入顺序。

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) 

下面的扩展方法 - Seq#toListMap可以ListMap s工作时是非常有用的。

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) 
+1

有一个ListMap的问题 - 用现有的键*改变*调用项目的顺序update()。例如:'ListMap(“a”→1,“b”→2).updated(“a”,2).toList'产生'List((b,2),(a,2))'。很不幸的我用例:( – 2017-02-08 09:51:16

20

虽然ListMap将保留插入顺序,它不是非常有效 - 例如查找时间是线性的。我建议你创建一个新的收集类,它包括immutable.HashMapimmutable.TreeMap。不可改变的地图应该被参数为immutable.HashMap[Key, (Value, Long)],其中在元组中的Long给你的指针到TreeMap[Long, Key]相应的条目。然后你在旁边保留一个进入计数器。此树形图将根据插入顺序对条目进行排序。

您可以实现以直接的方式插入和查找 - 增加计数器,插入到哈希表,并插入到反密钥对成树状图。您使用哈希映射进行查找。

您可以通过使用树地图实现迭代。

要实现删除,你必须删除从哈希表的键值对,并使用该指数从数组中删除从树图的对应条目。

+3

+1。在不久的将来,具有STDLIB这样一个集合的任何机会呢? – missingfaktor 2012-02-16 15:59:51

+0

这还没有计划,但如果对斯卡拉讨论内部插件邮件列表透露了很多人想要这个,那么为什么不。 – axel22 2012-02-16 16:07:42

+1

你愿意来阐述为什么? – axel22 2012-11-06 19:23:28