mutable.ListMap的奇怪行为

时间:2016-01-17 07:23:24

标签: scala collections

我正在尝试使用ListMap中的值过滤List。但订单未在输出mutable.ListMap中维护。这是一个简化的代码。由于存在约束和验证检查,我无法使用filter

执行此操作

这是我的代码,

val inMap = scala.collection.immutable.ListMap((1,5),(2,4),(3,5),(7,6))
val alist= List(1,2,3)
val mutableTempMap = scala.collection.mutable.ListMap.empty[Int, Int]

for (jkey <- alist) {
  inMap.get(jkey) match {
    case Some(y) => mutableTempMap(jkey) = y
    case None    =>
  }
}

mutableTempMap

输出:

scala.collection.mutable.ListMap[Int,Int] = Map(3 -> 5, 1 -> 5, 2 -> 4)

预期输出

scala.collection.mutable.ListMap[Int,Int] = Map(1 -> 5, 2 -> 4, 3 -> 5)

3 个答案:

答案 0 :(得分:1)

如果您使用不可变ListMap,则会保留订单。可变性(颤抖)可以通过var实现。

var ilm = collection.immutable.ListMap.empty[Int,Int]
ilm = ilm + (1 -> 5)
ilm = ilm + (2 -> 4)
ilm = ilm + (3 -> 5)
// ilm: immutable.ListMap[Int,Int] = Map(1 -> 5, 2 -> 4, 3 -> 5)

答案 1 :(得分:1)

首先,由于ListMap是幕后的单链表,因此可变版本与var immutable完全没有任何性能。

从那里开始,它确实有一个奇怪的插入模式,所以让我们测试一下:

val m = collection.mutable.ListMap.empty[Int,Int]
(1 to 10).foreach {i =>
   m(i) = i
   println(m)
}

生成此输出。注意每次插入后,尾部是如何反转的,所以有你的答案。

Map(1 -> 1)
Map(2 -> 2, 1 -> 1)
Map(3 -> 3, 1 -> 1, 2 -> 2)
Map(4 -> 4, 2 -> 2, 1 -> 1, 3 -> 3)
Map(5 -> 5, 3 -> 3, 1 -> 1, 2 -> 2, 4 -> 4)
Map(6 -> 6, 4 -> 4, 2 -> 2, 1 -> 1, 3 -> 3, 5 -> 5)
Map(7 -> 7, 5 -> 5, 3 -> 3, 1 -> 1, 2 -> 2, 4 -> 4, 6 -> 6)
Map(8 -> 8, 6 -> 6, 4 -> 4, 2 -> 2, 1 -> 1, 3 -> 3, 5 -> 5, 7 -> 7)
Map(9 -> 9, 7 -> 7, 5 -> 5, 3 -> 3, 1 -> 1, 2 -> 2, 4 -> 4, 6 -> 6, 8 -> 8)
Map(10 -> 10, 8 -> 8, 6 -> 6, 4 -> 4, 2 -> 2, 1 -> 1, 3 -> 3, 5 -> 5, 7 -> 7, 9 -> 9)

我可能会认为这是一个错误,尽管没有订购地图。

答案 2 :(得分:0)

mutable.ListMap维持订单的假设是错误的。它不在合同中。最好的选择是使用LinkedHashMap

另见:

Scala Map implementation keeping entries in insertion order?