为什么更改用作 HashMap 中键的对象的哈希码会使

Why does changing the hashcode of an object used as a key in a HashMap make a lookup return null?(为什么更改用作 HashMap 中键的对象的哈希码会使查找返回 null?)

本文介绍了为什么更改用作 HashMap 中键的对象的哈希码会使查找返回 null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下场景:

Object o1 = new Object();
Object o2 = new Object();

HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put(o1, o2);

boolean test1 = map.get(o1) == o2; // This evaluates to true

// Now lets say we alter the state of o1:
o1.setSomeInternalState(Object newState);

boolean test2 = map.get(o1) == o2; // This evaluates to false, because now map.get(o1) returns null

假设 o1 的类已覆盖 equals()hashCode().

Assume that the class for o1 has overridden equals() and hashCode().

我在调试过程中遇到了这个问题,因为我在某些业务逻辑中使用的一个特定对象上明确覆盖了 equalshashCode.我可以完全理解为什么当我改变它的状态时对象的哈希码会改变,但是为什么 map.get(o1) 会因为它返回 null 呢?只有一个对象,所以key的hashcode不应该匹配吗?

I've encountered this issue during debugging because I had explicitly overridden equals and hashCode on one particular object I'm using in some business logic. I can fully appreciate why the hashcode of the object changes when I alter its state, but why should the map.get(o1) return null because of it? There is only one object, so shouldn't the key's hashcode match?

推荐答案

HashMap 类通过 运行键的 hashCode 将键映射到值哈希函数.哈希函数用于创建桶数组的索引.例如,very 原始散列函数将是 hashCode % tableSize.更改键的 hashCode 会更改哈希函数创建的索引,这意味着在该存储桶中找不到任何内容.

The HashMap class maps keys to values by running the hashCode of the key through a hash function. The hash function is used to create an index into an array of buckets. For example, a very primitive hash function would be hashCode % tableSize. Changing the key's hashCode would alter the index created by the hash function, meaning there is nothing to be found in that bucket.

我们运行一个例子,假设初始hashCode为15,表大小为4:

Let's run an example, assuming that the initial hashCode is 15 and the table size is 4:

                         ┌----------------------┐
15 (initial hashCode) -> | hashCode % tableSize | -> index 3
                         |    (hash function)   |
                         └----------------------┘

所以让我们在索引 3 处插入值:

So let's insert the value at index 3:

  ┌------┐
0 | null |
  |------|
1 | null |
  |------|
2 | null |
  |------|
3 | key! | <- insert
  └------┘

现在让我们修改密钥的 hashCode 使其现在是 13:

Now let's modifiy the key's hashCode so that it is now 13:

                          ┌----------------------┐
13 (modified hashCode) -> | hashCode % tableSize | -> index 1
                          |    (hash function)   |
                          └----------------------┘

索引 1 是什么?什么都没有,null.

What's at index 1? Nothing, null.

这里已经简化了很多事情.在真正的哈希表实现中,哈希函数要创建更均匀的分布要复杂得多.此外,存储桶是链表,因此可以处理冲突.

A lot of things have been simplified here. In a real hash table implementation, the hash function is much more complex to create a more even distribution. Also, the buckets are linked-lists so collisions can be handled.

这篇关于为什么更改用作 HashMap 中键的对象的哈希码会使查找返回 null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:为什么更改用作 HashMap 中键的对象的哈希码会使

基础教程推荐