Scala中的嵌套默认地图
我正在
Scala中构建嵌套的地图,其中外层和内部地图都使用“withDefaultValue”方法.例如,以下内容:
val m = HashMap.empty[Int,collection.mutable.Map[Int,Int]].withDefaultValue( HashMap.empty[Int,Int].withDefaultValue(3)) m(1)(2) res: Int = 3 m(1)(2) = 5 m(1)(2) res: Int = 5 m(2)(3) = 6 m res : scala.collection.mutable.Map[Int,scala.collection.mutable.Map[Int,Int]] = Map() 所以地图,当由适当的钥匙处理时,给我回到我所投入的东西.但是,地图本身就是空的!即使m.size在此示例中返回0.任何人都可以解释这里发生了什么吗? 解决方法
简短答案
这绝对不是一个bug. 长答案 withDefaultValue的行为是在Map中存储一个默认值(在你的情况下是一个可变地图),以便在它们的键不存在的情况下返回.这与在没有找到密钥时插入到地图中的值不同. 我们来看看发生了什么事情.如果我们将默认地图作为单独的变量拖出来,我们可以随意查看,这将会更容易理解.我们称之为默认 import collection.mutable.HashMap val default = HashMap.empty[Int,Int].withDefaultValue(3) 所以默认是一个可变地图(有自己的默认值).现在我们可以创建m并给出默认值作为默认值. import collection.mutable.{Map => MMap} val m = HashMap.empty[Int,MMap[Int,Int]].withDefaultValue(default) 现在每当使用缺少的密钥访问m时,它将返回默认值.请注意,这与您的行为完全相同,因为将DefaultValue定义为: def withDefaultValue (d: B): Map[A,B] 请注意,它是d:B而不是d:=> B,所以每次默认访问时都不会创建一个新的地图;它将返回相同的精确对象,我们称之为默认对象. 所以让我们看看会发生什么: m(1) // Map() 由于键1不在m中,默认值为默认值.这时默认是一个空的地图. m(1)(2) = 5 由于m(1)返回默认值,此操作默认存储5作为键2的值.因为m(1)完全解析为一个单独的映射到默认值,所以没有写入地图m.我们可以查看默认值: default // Map(2 -> 5) 但是正如我们所说,m保持不变 m // Map() 现在,如何实现你真正想要的?而不是使用withDefaultValue,你想使用getOrElseUpdate: def getOrElseUpdate (key: A,op: ? B): B 注意我们如何看到op:=> B’这意味着每次需要时,参数op都将被重新评估.这样我们可以在其中放置一个新的Map,并为每个无效的密钥分别创建一个Map.让我们来看看: val m2 = HashMap.empty[Int,Int]] 这里不需要默认值. m2.getOrElseUpdate(1,HashMap.empty[Int,Int].withDefaultValue(3)) // Map() 键1不存在,所以我们插入一个新的HashMap,并返回该新值.我们可以检查它是否按照我们预期插入.请注意,1映射到新添加的空地图,并且由于上述行为,它们没有添加到任何地方. m2 // Map(1 -> Map()) 同样,我们可以按预期更新地图: m2.getOrElseUpdate(1,Int].withDefaultValue(1))(2) = 6 并检查是否添加: m2 // Map(1 -> Map(2 -> 6)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |