我有一个空Map,默认值为ListList空。
val map: Map[String, ListBuffer[String]] = Map.empty.withDefaultValue(ListBuffer())
当我寻址到它尚不存在的键并想要附加一些值时,它执行了意外的操作:
// map += "one" -> ListBuffer("l")
map("one") += "lo"
map("two") += "lol"
map("one") += "la"
println(map("one").result)
我认为它应该打印List(lo, la)
,但它打印List(lo, lol, la)
。for(m <- map) println(m)
不打印任何内容。如果我取消注释map += "one" -> ListBuffer("t")
,它将打印正确的List(l, lo, la)
,但是println("two(or any other key)")
打印List(lo, lol, la)
。我该如何解决?有什么我不知道的地方吗?
发生这种情况是因为您的地图具有默认值-ListBuffer()
当您尝试向地图添加内容时:map("one") += "lo"
实际在地图中查找键one
时一无所获并获得默认值-ListBuffer()
。之后,lo
附加到ListBuffer()
,现在默认值为ListBuffer("lo")
。two
和one
键重复相同的算法。这样,键one
(以及其余键)将永远不会放置在地图上。
而且您正在使用不可变的地图,添加后它会创建新的地图。如果要使用所有键和值来收集地图,则可以使用foldLeft:
val map: Map[String, ListBuffer[String]] = Map.empty.withDefaultValue(ListBuffer())
val newMap = Seq(
"one" -> "lo",
"two" -> "lol",
"one" -> "la"
).foldLeft(map){
case (accMap, (key, value)) => accMap + (key -> (value +: accMap(key)))
}
println(newMap("one").result) // List(la, lo)
println(newMap) // Map(one -> ListBuffer(la, lo), two -> ListBuffer(lol))
或您可以使用易变地图:
val map: mutable.Map[String, ListBuffer[String]] = mutable.Map.empty.withDefaultValue(ListBuffer())
map.update("one", "lo" +: map("one"))
map.update("two", "lol" +: map("two"))
map.update("one", "la" +: map("one"))
println(map("one").result) // List(la, lo)
println(map) // Map(one -> ListBuffer(la, lo), two -> ListBuffer(lol))
如果您有这样的元组序列
val keyValue = Seq(
"one" -> "lo",
"two" -> "lol",
"one" -> "la"
)
我建议您这样使用groupBy
println(x.groupBy(_._1).mapValues(_.map(_._2)))
由于在Scala中使用可变数据结构不是很好,因此您可能会考虑设计并尝试对其进行更改。
为什么无法从代码中获得所需的输出是因为您有一个不可变的Map,如果要更新该Map,则需要一个可变的map,它为您提供方法更新,这里您在map("one") += "la"
中取了什么发生这种情况时,当您执行map(“ one”)为空时会得到listBuffer,然后使用"lo"
和+=
使用"two" and "one"
更新该listBuffer,但是如果您看到那里的地图仍然为空在地图中没有任何内容,因为您没有更新地图,因此您已经更新了listBuffer。您是从map("one")
获得的,这是一个空的listBuffer。
如果您在打印中使用anystring,您将得到相同的结果
println(map("").result) //List("lo", "lol", "la")