Java HashMap如何在内部存储条目 [英] How does Java HashMap store entries internally

查看:112
本文介绍了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();

现在

  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)将返回valueOriginal
map.get(keyClone)将返回valueOriginal

此外,如果您在将密钥放入地图后将其更改,则无法检索原始值。因此,例如

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

现在,map.get(keyOriginal)将返回null





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

编辑
So据我了解,我认为它通过将Entry键作为最终变量来工作。

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

(docjar.com/html/api/java/util/HashMap.java.html)。因此,即使我在将密钥放入地图后进行了变更,原始密钥仍然保留。我的理解是否正确?但即使保留原始密钥引用,仍然可以改变其内容。因此,如果内容发生了变化,并且K,V仍然保存在原始位置,检索工作是如何进行的?
$ b 编辑 $ b如果您在将键放入哈希映射后进行变更,$ b检索将会失败。因此,不建议您拥有可变的hashmap键。

解决方案

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


$ b $ p map.keySet )只是迭代散列表,返回它拥有的每个条目的键。


Say you have a key class (KeyClass) with overridden equals, hashCode and clone methods. Assume that it has 2 primitive fields, a String (name) and an int (id).

Now you define

KeyClass keyOriginal, keyCopy, keyClone;

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

Now

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

So as far as a HashMap is concerned, keyOriginal, keyCopy and keyClone are indistinguishable.

Now if you put an entry into the HashMap using keyOriginal, you can retrieve it back using keyCopy or keyClone, ie

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

Additionally, if you mutate the key after you have put it into the map, you cannot retrieve the original value. So for eg

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

Now map.get(keyOriginal) will return null

So my question is

when you say map.keySet(), it will return back all the keys in the map. How does the HashMap class know what are the complete list of keys, values and entries stored in the map?

EDIT So as I understand it, I think it works by making the Entry key as a final variable.

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

(docjar.com/html/api/java/util/HashMap.java.html). So even if I mutate the key after putting it into the map, the original key is retained. Is my understanding correct? But even if the original key reference is retained, one can still mutate its contents. So if the contents are mutated, and the K,V is still stored in the original location, how does retrieval work?

EDIT retrieval will fail if you mutate the key after putting into the hashmap. Hence it is not recommended that you have mutable hashmap keys.

解决方案

HashMap maintains a table of entries, with references to the associated keys and values, organized according to their hash code. If you mutate a key, then the hash code will change, but the entry in HashMap is still placed in the hash table according to the original hash code. That's why map.get(keyOriginal) will return null.

map.keySet() just iterates over the hash table, returning the key of each entry it has.

这篇关于Java HashMap如何在内部存储条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆