HashMap优化的影响,它将与每个条目关联的哈希代码缓存到其get方法中

来自第46页“有效的Java”Joshua Bloch。 第9项:当你重写equals时,ALways会覆盖hashCode

  • 某些类PhoneNumber会覆盖equals()并且不会覆盖hashCode()
  • “涉及两个实例:一个用于插入HashMap,另一个用于(尝试)检索。” …“…即使两个实例碰巧哈希到同一个桶, get方法几乎肯定会返回null ,因为HashMap有一个优化缓存与每个条目关联的哈希代码,并且不需要检查如果哈希码不匹配,则对象相等。“

问题是 – 如果“两个实例碰巧哈希到同一个桶”,为什么’get’将返回’null’?

  • 什么是HashMap优化的角色(没有得到正确的实例)“兑现…”?

  • 只是针对这种情况 – “这两个实例碰巧哈希到同一个桶” – 如果HashMap困扰“如果哈希码不匹配则对象相等”会怎么样?

如果“两个实例碰巧哈希到同一个桶”,为什么’get’将返回’null’? 什么是HashMap优化的角色(没有得到正确的实例)“兑现…”?

关键句是

如果哈希码不匹配,[…]不会检查对象是否相等。

因此,即使密钥散列到同一个桶, .equals可能不会为相关元素调用.equals (由于缓存优化)(因为即使哈希代码也不匹配)。 因此,即使相关元素驻留在同一个桶中,也可能永远不会通过.equals进行比较,因此不会“找到”。

只是针对这种情况 – “这两个实例碰巧哈希到同一个桶” – 如果HashMap困扰“如果哈希码不匹配则对象相等”会怎么样?

如果它没有这个优化,并且实际上检查了相应存储桶中所有元素的.equals并且如果两个哈希值恰好散列到同一个存储桶,那么get-method将返回正确的元素。 (但这将是纯粹的运气,因为如果对象不相等,则无法保证两个哈希值首先映射到同一个桶。)

如果“两个实例碰巧哈希到同一个桶”,为什么’get’将返回’null’

只有当hashCodes不相等时才会这样做。 它可以做到这一点,因为通过hashCode()的契约,不相等的hashCodes意味着不相等的对象。 (请注意,反之亦然:语言律师请注意。)