Java HashMap如何在内部存储条目

Bas*_*Roy 9 java hashmap

假设您有一个带有重写的equals,hashCode和clone方法的键类(KeyClass).假设它有2个原始字段,一个String(名称)和一个int(id).

现在你定义

KeyClass keyOriginal, keyCopy, keyClone;

keyOriginal = new KeyClass("original", 1);
keyCopy = new KeyClass("original", 1);
keyClone = KeyClass.clone();
Run Code Online (Sandbox Code Playgroud)

现在

keyOriginal.hashCode() == keyCopy.hashCode() == keyClone.hashCode()
keyOriginal.equals(keyCopy) == true
keyCopy.equals(keyClone) == true
Run Code Online (Sandbox Code Playgroud)

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

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

map.put(keyOriginal, valueOriginal);
map.get(keyCopy) will return valueOriginal
map.get(keyClone) will return valueOriginal
Run Code Online (Sandbox Code Playgroud)

此外,如果在将密钥放入地图后改变密钥,则无法检索原始值.所以对于例如

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

Now map.get(keyOriginal) will return null
Run Code Online (Sandbox Code Playgroud)

所以我的问题是

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

编辑 所以我理解它,我认为它的工作原理是将Entry键作为最终变量.

static class Entry<K,V> implements Map.Entry<K,V> { 
  final K key; 
Run Code Online (Sandbox Code Playgroud)

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

如果在放入hashmap后改变键,EDIT检索将失败.因此,不建议您使用可变的hashmap键.

Lou*_*man 9

HashMap维护一个条目表,引用相关的键和值,根据它们的哈希码组织.如果改变键,则哈希码将改变,但是条目HashMap仍然根据原始哈希码放在哈希表中.这就是为什么map.get(keyOriginal)会返回null.

map.keySet() 只是遍历哈希表,返回它所拥有的每个条目的密钥.