Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HashMap如何在内部存储条目_Java_Hashmap - Fatal编程技术网

Java HashMap如何在内部存储条目

Java HashMap如何在内部存储条目,java,hashmap,Java,Hashmap,假设您有一个包含重写的equals、hashCode和clone方法的键类(KeyClass)。假设它有两个基本字段,一个字符串(名称)和一个int(id) 现在你定义 KeyClass keyOriginal, keyCopy, keyClone; keyOriginal = new KeyClass("original", 1); keyCopy = new KeyClass("original", 1); keyClone = KeyClass.clone(); 现在 因此,就Hash

假设您有一个包含重写的equals、hashCode和clone方法的键类(KeyClass)。假设它有两个基本字段,一个字符串(名称)和一个int(id)

现在你定义

KeyClass keyOriginal, keyCopy, keyClone;

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

因此,就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; 
静态类条目实现Map.Entry{
最终K键;
(docjar.com/html/api/java/util/HashMap.java.html)。因此,即使我在将密钥放入地图后对其进行变异,原始密钥仍会保留。我的理解正确吗?但即使保留原始密钥引用,也可以对其内容进行变异。因此,如果内容发生变异,且K,V仍存储在原始位置,检索工作如何

编辑
如果在放入hashmap后对键进行变异,检索将失败。因此,不建议您使用可变hashmap键。

hashmap
维护一个条目表,其中引用了相关的键和值,并根据它们的哈希代码进行组织。如果对键进行变异,则哈希代码将更改,但根据原始哈希代码,
HashMap
中的ntry仍然放在哈希表中。这就是为什么
map.get(keydoriginal)
将返回null


map.keySet()
只需在哈希表上迭代,返回它拥有的每个条目的键。

如果您更改条目而不是哈希代码,您是安全的。因此,将哈希代码中的所有字段设置为等于和比较,这被认为是最佳做法,
final
和不可变。

简单地说,哈希映射是comp中的一个对象包含键和值的uter内存。每个键都是唯一的(阅读hashcode),每个键指向一个值

在您的代码示例中,在每种情况下,映射中的值都是相同的,因为键是相同的。当您更改键时,无法为其获取值,因为您从未使用经过修改的键将项添加到HashMap中

如果添加了行:

map.put("mutated", 2);

在更改密钥之前,您将不再获得空值。

为什么不自己查看源代码,它是公共的,易于访问。如果不是,它现在就不是一个数据结构了,是吗?您认为它如何能够查找您想要的特定密钥?出于好奇。查找单个密钥只是一个计算问题对hashCode进行拉丁化,然后使用equals比较每个冲突的键。但是HashMap需要知道存储在其中的所有键是什么;而不需要客户端传入键。因此Louis下面的答案看起来像是这样的。谢谢。“如果您更改了一个键,则哈希代码将更改,但HashMap中的条目仍然根据原始哈希代码放置在哈希表中。“我阅读了源代码。据我所知,我认为它的工作原理是将Entry键作为最终变量。静态类Entry实现Map.Entry{final K key;()。因此,即使我在将密钥放入映射后对其进行了变异,原始密钥仍会保留。我的理解正确吗?它包含对该密钥的引用。如果对该密钥进行变异,则基本上,
HashMap
entrySet()
将看到修改后的密钥,但
get(key)
将查找错误的位置,因此当您尝试
map.get(键)时,它将返回
null
。基本上,在
地图中拥有可变键只会自找麻烦,而实际上,在
地图中对键进行变异就像是在膝盖上开枪一样。再次感谢。但我仍然不明白的是,在它们里面有相同字段值的keyOriginal和keyCopy。现在你把keyOriginal在映射中。假设它进入内部hashmap条目表中的位置100。现在,您改变了keyOriginal。它仍然存储在位置100。现在,如果您说map.get(keyCopy),它确实返回原始关联值。如果keyOriginal.equals(keyCopy),它如何能够做到这一点是假的?你测试过了吗?如果这是真的,我会非常惊讶。我强烈希望
map.get(keyCopy)
返回
null
。是的,我已经测试过了。我将在一个新问题中添加测试代码。我不能在这里添加,因为它太长了。谢谢。好信息。--“如果您更改了条目,但没有更改哈希代码,那么您是安全的。”--我想补充一点,您仍然不安全,因为equals将失败。因此,我想可以肯定地说,如果您更改了密钥(哈希代码不同,equals为false)添加到映射后,检索将失败。除非这是您想要的。;)如果它必须是可变的,您可以删除该键,更新它并将其添加回。只有当它是映射的键(或基于相同原因的集合元素)时更改该键才是问题。是的,这不是我在本例中的意图。
map.put("mutated", 2);