Reputation: 3922
I am trying to filter a ListMap
with values in a List
. But the order is not maintained in output mutable.ListMap
. This is a simplified code. As there are constraints and validation checks to be done, I cant do this with filter
.
Here is my code,
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
Output:
scala.collection.mutable.ListMap[Int,Int] = Map(3 -> 5, 1 -> 5, 2 -> 4)
Expected Output
scala.collection.mutable.ListMap[Int,Int] = Map(1 -> 5, 2 -> 4, 3 -> 5)
Upvotes: 0
Views: 115
Reputation: 3922
The assumption that mutable.ListMap
maintains the order is wrong. Its not in the contract. The best option is to use LinkedHashMap
.
Also see:
Scala Map implementation keeping entries in insertion order?
Upvotes: 0
Reputation: 48775
First of all, because of the ListMap
being a singly linked list behind the scenes, you gain absolutely no performance with the mutable version, versus the var immutable.
Appart from that, it really has a weird insert pattern, so let's test it out:
val m = collection.mutable.ListMap.empty[Int,Int]
(1 to 10).foreach {i =>
m(i) = i
println(m)
}
Produces this output. Notice how after each insert, the tail is reversed, so there is your answer.
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)
I would probably vote this being a bug, despite the fact that maps are not ordered.
Upvotes: 1
Reputation: 51271
Order is maintained if you use an immutable ListMap
. Mutability (shudder) can be achieved with a 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)
Upvotes: 1