字符串作为hashmap中的键

ric*_*mes 16 java

我在过去一小时内阅读了很多帖子,但是我仍然不太清楚使用不可变对象作为Hashmap中的键的概念.我有一个哈希映射,其键作为字符串.hashmap中的值是MyStore,其中MyStore表示有关我拥有的商店的信息.String表示地址.在我的代码中,我的逻辑是,我首先在地图中查找该键,如果存在 - >获取其值,如果它不存在则将其放入hashmap中.我的经理告诉我,密钥将来会改变,那就是我的商店的地址将来会改变.他说在这种情况下,我首先检查密钥是否存在的逻辑不起作用.我不明白他的意思.我想非常清楚地理解以下几点 -

  1. hashmap的可变键和不可变键之间的区别.
  2. 如果使用可更改的不可变密钥会发生什么? - 我知道这没有意义,但我想清楚地了解我的经理在这里谈论的内容.
  3. 有些帖子谈论字符串,如果在哈希码中使用哈希码作为键,那么这意味着什么?
  4. 如果让我说我在我的hashmap中使用可变对象作为实现hashcode和equals的键,那么它会起作用吗?我假设它会,因为如果密钥更改,contains方法将查看密钥是否存在.如果它不存在,它将入门这样你就可以得到在未来它.

如果之前已经讨论过,我并不是要创建一个重复的帖子.如果我错过阅读有关我所有问题答案的帖子,请指出.如果没有,请以外行的方式解释我的上述问题,以便将来对其他读者有用:).随意编辑我的帖子的主题,以便将来如果有人有类似的问题,他们会直接降落在这里:)

bow*_*ore 28

第一:HashMap是如何工作的?

基本上它有一个数组,当你在地图中放置一个键值对时,它存储在数组中的一个位置.根据hashCode()传递给散列方法的键的结果选择数组中的位置.这是为什么?好吧,如果您请求某个键的值,则可以简单地重新计算数组中用于查找键及其关联值的索引,以便再次在数组中查找索引.(需要更多的逻辑来处理映射到同一索引的键,但我只是想让你理解基本机制)然后equals()用于验证计算索引处的键是否确实是所请求的键.

  1. 从这一点来看,应该更清楚为什么不可变密钥比可变密钥更好.不可变键将始终保持相同的hashCode()值,并且哈希函数将再次找到正确的桶(= hashMap的数组中的索引).

    这并不意味着可变密钥无法正常工作.如果密钥上的突变不影响哈希代码,或者只要使用hashMap,密钥就不会发生变异,那么可变密钥将起作用.

  2. 一个不可变的密钥如何改变?好吧,密钥本身可能无法更改,但键值映射可能会在业务逻辑中发生变化.如果您使用地址作为密钥创建地图,则依赖于商店地址不会更改的事实.如果商店的地址发生变化,您将无法使用新地址作为密钥在地图中找到它.你的经理有一个有效的观点.

  3. 在Map中查找键的速度很大程度上取决于计算hashCode的速度.对于String,此计算将循环遍历String中的所有字符.如果你使用长字符串作为键并且有很多Map访问权限,这可能会导致性能瓶颈.因此,Java的String实现会缓存哈希值,因此它只会被计算一次.但是,如果String再次使用相同的实例,则只会避免计算哈希代码(新实例将不具有缓存值).你可能intern()使用了你所使用的按键,但只有在可以证明确实存在性能瓶颈的情况下才考虑这一点,因为String实习会带来自己的开销.

  4. 如1中所述:如果哈希码不受突变影响,则可变密钥可以工作.例如,使用Customer作为密钥,其中hashCode()仅基于客户的名称,然后只允许更改名称但允许其他值更改的Customer实现是可靠的密钥.

  • @AntonBelev Map实现(特别是一个专用的)如何能够知道密钥的哈希代码何时发生了变化?Map可以在每次获取之前检查所有包含的键,但这只会破坏Map的用途:快速获取与键关联的值. (6认同)