小编典典

Java HashMap如何在内部存储条目

java

假设您有一个键类(KeyClass),该键类具有重写的equals,hashCode和clone方法。假设它有2个基本字段,一个String(名称)和一个int(id)。

现在您定义

KeyClass keyOriginal, keyCopy, keyClone;

keyOriginal = new KeyClass("original", 1);
keyCopy = new KeyClass("original", 1);
keyClone = KeyClass.clone();

现在

keyOriginal.hashCode() == keyCopy.hashCode() == keyClone.hashCode()
keyOriginal.equals(keyCopy) == true
keyCopy.equals(keyClone) == true

因此,就HashMap而言,keyOriginal,keyCopy和keyClone是无法区分的。

现在,如果您使用keyOriginal将条目放入HashMap,则可以使用keyCopy或keyClone将其检索回来,即

map.put(keyOriginal, valueOriginal);
map.get(keyCopy) will return valueOriginal
map.get(keyClone) will return valueOriginal

此外,如果在将密钥放入地图后对其进行了变异,则无法获取原始值。所以例如

keyOriginal.name = "mutated";
keyOriginal.id = 1000;

Now map.get(keyOriginal) will return null

所以我的问题是

当您说map.keySet()时,它将返回地图中的所有键。HashMap类如何知道映射中存储的键,值和条目的完整列表?

编辑 据我所知,我认为通过将Entry键作为最终变量来工作。

static class Entry<K,V> implements Map.Entry<K,V> { 
  final K key;

(docjar.com/html/api/java/util/HashMap.java.html)。因此,即使我在将密钥放入地图后对其进行了变异,原始密钥也会保留下来。我的理解正确吗?但是,即使保留了原始的键引用,也仍然可以更改其内容。因此,如果内容发生突变,并且K,V仍存储在原始位置,则检索如何工作?

*如果将密钥放入哈希表后进行突变,则 *EDIT 检索将失败。因此,不建议您使用可变的哈希映射键。


阅读 212

收藏
2020-10-15

共1个答案

小编典典

HashMap维护一个条目表,并根据其哈希码组织对相关键和值的引用。如果您更改键,则哈希码将更改,但输入项HashMap仍会根据原始哈希码放置在哈希表中。这就是为什么map.get(keyOriginal)将返回null
的原因。

map.keySet() 只是遍历哈希表,返回它具有的每个条目的键。

2020-10-15