我正在使用ListMap,因为我需要保持插入顺序。初始化后,它似乎有效。但当我打电话给它更新时,订单搞砸了。 1-为什么? 2-是否还有其他MapLike
没有出现此问题,如果没有,我应该如何更新地图而不会出现问题?
scala> import scala.collection.immutable.ListMap
import scala.collection.immutable.ListMap
scala> val a = ListMap(0 -> "A", 1 -> "B", 2 ->"C")
a: scala.collection.immutable.ListMap[Int,String] = Map(0 -> A, 1 -> B, 2 -> C)
scala> a.foreach(println)
(0,A)
(1,B)
(2,C)
scala> val b = a.updated(1, "D")
b: scala.collection.immutable.ListMap[Int,String] = Map(0 -> A, 2 -> C, 1 -> D)
scala> b.foreach(println)
(0,A)
(2,C)
(1,D)
答案 0 :(得分:3)
我找不到任何存在的具有所需属性的不可变集合。但它可以手动制作。
import scala.collection.immutable.{IntMap, Map, MapLike}
class OrderedMap[K, +V] private[OrderedMap](backing: Map[K, V], val order: IntMap[K], coorder: Map[K, Int], extSize: Int)
extends Map[K, V] with MapLike[K, V, OrderedMap[K, V]] {
def +[B1 >: V](kv: (K, B1)): OrderedMap[K, B1] = {
val (k, v) = kv
if (backing contains k)
new OrderedMap(backing + kv, order, coorder, extSize)
else new OrderedMap(backing + kv, order + (extSize -> k), coorder + (k -> extSize), extSize + 1)
}
def get(key: K): Option[V] = backing.get(key)
def iterator: Iterator[(K, V)] = for (key <- order.valuesIterator) yield (key, backing(key))
def -(key: K): OrderedMap[K, V] = if (backing contains key) {
val index = coorder(key)
new OrderedMap(backing - key, order - index, coorder - key, extSize)
} else this
override def empty: OrderedMap[K, V] = OrderedMap.empty[K, V]
}
object OrderedMap {
def empty[K, V] = new OrderedMap[K, V](Map.empty, IntMap.empty, Map.empty, 0)
def apply[K, V](assocs: (K, V)*): OrderedMap[K, V] = assocs.foldLeft(empty[K, V])(_ + _)
}
这里order
是保留的插入顺序图(可能带有“洞”)。有效处理元素移除所需的coorder
特殊字段。 extSize
基本上是order.lastkey + 1
,但更直接
现在您可以验证
val a = OrderedMap(0 -> "A", 1 -> "B", 2 -> "C")
a.foreach(println)
val b = a.updated(1, "D")
b.foreach(println)
打印
(0,A)
(1,B)
(2,C)
和
(0,A)
(1,D)
(2,C)
答案 1 :(得分:1)
来自1->D
&#34;此方法允许用户创建带有附加映射的新地图 从关键到价值。&#34;
请注意,它没有说&#34;具有不同的现有密钥值&#34;。因此,当您使用1->C
进行更新时,这是一个新的/额外的映射。因此它出现在列表的末尾,保留了插入顺序。旧映射{{1}}不再出现在地图中。
所以它没有&#34;搞砸了#34;这不是问题。它正在执行它记录的操作,映射按插入顺序排列。