【发布时间】:2012-03-25 01:43:50
【问题描述】:
假设您有一个键类 (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仍然保存在原来的位置,那么检索是如何进行的呢?
编辑 如果您在放入哈希映射后更改密钥,检索将失败。因此,不建议您使用可变的 hashmap 键。
【问题讨论】:
-
为什么不自己查看源代码,它是公开且易于访问的
-
如果不是这样,它现在就不是一个数据结构了,不是吗?您认为它如何能够查找您想要的特定密钥?
-
The source 对于好奇的人。
-
查找单个键只是计算hashCode然后使用equals比较每个碰撞的键的问题。但是 HashMap 需要知道其中存储的所有键是什么;没有客户端传递密钥。所以下面 Louis 的回答看起来是这样的。