有一个关于他们为什么要求使用不可变对象作为字典中的键的问题。
当我最近使用字典(显然不是为了哈希表的目的)将 Xml 节点对象作为键放置时,这个问题实际上出现在我的脑海中。然后我在使用过程中多次更新节点。
那么“使用不可变密钥”的真正含义是什么?
有一个关于他们为什么要求使用不可变对象作为字典中的键的问题。
当我最近使用字典(显然不是为了哈希表的目的)将 Xml 节点对象作为键放置时,这个问题实际上出现在我的脑海中。然后我在使用过程中多次更新节点。
那么“使用不可变密钥”的真正含义是什么?
当您将键插入哈希表时,哈希表会询问键的哈希码,并将其与键本身和相关值一起记住。当您稍后执行查找时,哈希表会向您要查找的键询问其哈希码,并且可以非常快速地找到表中具有相同哈希码的所有键。
只要哈希表中的键在其生命周期中保持相同的哈希码,这一切都很好 - 但如果它们是可变的(并且在插入哈希表后发生突变),那么通常哈希码会改变,此时搜索时永远找不到该条目。
当然,这只适用于影响平等的突变。例如,如果您Person
使用名称和生日对实体进行哈希处理,但由于某种原因,只有名称用于相等(因此在计算哈希码时仅使用名称),那么您可以将 aPerson
作为键,更改它的生日,以后仍然可以再次查找它,没有任何问题。
字典根据键的哈希码将项目放在桶中。如果您添加一个项目,然后更改其密钥,您将无法再找到该项目。
如果您使用新的键值查找它,字典将在不同的桶中查找,如果您使用旧键值,字典将找到它所在的桶,但键不再匹配。
字典类型是键和值之间的映射。映射将使用键的各种属性在内部字典存储中为其分配一个槽。在大多数情况下,它只是将属性简化为一个int
值。
如果一个键随时间变化,那么它的属性可能会开始映射到表中的不同索引。因此,该键将不再能够检索它最初在表中映射到的值。不可变类型完全避免了这种情况,因为它们永远不会改变。因此它们的映射始终是一致的