斯卡拉版本:3.1
我想創建一個 String -> Int 映射,每個鍵可能指向許多 Int。
因此我選擇了默認 mutable 的 map Buffer[Int]。
但似乎所有的鍵總是指向同一個Buffer[Int]
請注意,第一個也很奇怪,在 m("a") = 1此之后它什么也不列印, =但默認值已更改,因此它 在 next 中列印兩個 1println。
另外,我如何解決mutable.Map's =被 's 覆寫Buffer的問題 =。Buffer如果密鑰不存在,我希望地圖插入一個新的,然后呼叫 =.buffer
import scala.collection.mutable
val m: mutable.Map[String, mutable.Buffer[Int]] =
mutable.HashMap.empty.withDefaultValue(mutable.Buffer.empty)
m("a") = 1
println(m) // Map()
m("a") = m("a") = 1
println(m) // Map(a -> ArrayBuffer(1, 1))
m("b") = m("b") = 2 // Map(a -> ArrayBuffer(1, 1, 2), b -> ArrayBuffer(1, 1, 2)) , not expecting this, key is correct but
println(m) // Map(a -> ArrayBuffer(1, 1, 2), b -> ArrayBuffer(1, 1, 2))
m("a") = m("a") = 2
println(m) // Map(a -> ArrayBuffer(1, 1, 2, 2), b -> ArrayBuffer(1, 1, 2, 2)) ,
// this is not as I expected. The keys are correct, however their values are all the same ArrayBuffer
uj5u.com熱心網友回復:
TL; DR:withDefaultValue在這里沒用。
注意的簽名withDefaultValue是:
def withDefaultValue(d: V): Map[K, V]
該引數d是按值而不是按名稱( => V) 獲取的,因此它只計算一次。因此,原始映射中不存在的任何鍵都將回傳您創建一次的相同空緩沖區。
你得到的withDefaultValue(和withDefault)是一個新的類似地圖的物件,而不是原始地圖。只有分配結果 ( m("a") = ...) 才會改變它。
注意:默認值僅用于應用。其他方法如 get、contains、iterator、keys 等不受 withDefaultValue 影響。
考慮這個例子:
val m = new HashMap[Integer, Buffer[String]]()
val mm = m.withDefault(_ => Buffer.empty)
mm(1).append("4")
mm(1) // ArrayBuffer()
您可能想要的是getOrElseUpdate(如果您愿意,可以定義一個輔助函式)帶有簽名
getOrElseUpdate(key: K, defaultValue: => V): V
注意defaultValue這次是如何按名稱呼叫的,每次呼叫都會創建一個新的緩沖區:
val m: mutable.Map[String, mutable.Buffer[Int]] =
mutable.HashMap.empty
def mm(key: String): mutable.Buffer[Int] = m.getOrElseUpdate(key, mutable.Buffer.empty)
mm("a") = 1
mm("b") = 2
// now buffers at `a` and `b` are distinct
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/440174.html
