@Stephen 给出了非常好的概念性解释。
简而言之:
- 当我们在 HashMap 中“放入”某些东西时,它在内部存储在一个“table”中,它是一个“Entry”数组"
- 现在它将存储在该表的哪个位置 (bucketIndex) 将根据要存储的键的“hashcode”来决定。在存储之前JVM 将检查该 bucketIndex 中是否存在任何“Entry”。当两个“键”具有相同的哈希码时,这种情况是可能的。现在如果有一个 入口 JVM 将进一步检查“key”本身是否与“键”已经存在。如果是,它会将其视为重复键,并在“Entry”中更新其各自的值。如果不是,它只会在相同的 bucket Index 中添加另一个条目。
- 在通过发送“key”从地图中“获取”值时,将运行类似的过程。首先“hashcode " 将被提取,并据此确定要查看的表的位置 (bucketIndex)。现在,如果该索引中没有内容,将返回“null”。否则...
- JVM 将转到该索引,并且可能存在多个“Entry”,因为多个对象可以具有相同的哈希码。现在 JVM 将在该 key 上调用“equals”方法来检查表中存在的 Key 是否与为检索值而发送的 inputKey 相同。如果 "equals" 返回 true,那么我们将获得所需的值。
所以一般来说,当且仅当 hashcode() 两者都返回相同的值并且 等于 时,一个键将被视为重复键 >() 将返回 true。
现在来回答你的问题“我添加一个新的 HashMap 作为键,它是否被视为重复键”,答案是肯定的,当且仅当你的新 HashMap 具有精确的与现有 HashMap 键相同的条目,即键、值对。
因为:
- 如果你看一下HashMap的hashcode()实现,你会看到它的hashcode是根据“Key”和“value”计算出来的。所以如果 2 个 hashmap 将具有相同的 集,则它们将具有相同的 hashcode()。
- HashMap 的 equals() 检查 Entry 是否相同。因此,如果两个 Hashmap 具有相同的 集,则它们是相等的。
现在看下面的代码演示这个概念:
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<Integer,Integer> keyMap=new HashMap<Integer, Integer>();
keyMap.put(2, 1020);
keyMap.put(3, 1352);
keyMap.put(23,1256);
System.out.println("hashcode keymap1:"+keyMap.hashCode());
HashMap<Integer,Integer> keyMap2=new HashMap<Integer, Integer>();
keyMap2.put(1, 100);
keyMap2.put(4, 152);
keyMap2.put(43,156);
System.out.println("hashcode keymap2:"+keyMap2.hashCode());
HashMap<HashMap<Integer,Integer>,String> mainMap=new HashMap<HashMap<Integer,Integer>,String>();
mainMap.put(keyMap, "1st value");
mainMap.put(keyMap2, "2ndvalue");
System.out.println(mainMap);
HashMap<Integer,Integer> keyMap3=new HashMap<Integer, Integer>();
keyMap3.put(23,1256);
keyMap3.put(3, 1352);
keyMap3.put(2, 1020);
System.out.println("hashcode keymap3:"+keyMap3.hashCode());
mainMap.put(keyMap3, "3rd value");
System.out.println(mainMap);
if(mainMap.containsKey(keyMap3))
System.out.println(" value retrieved is :"+mainMap.get(keyMap3));
else
System.out.println("key not found");
}
在这里您可以观察到 keymap 和 keymap3 具有相同的 key、value 和相同的 hashcode 集。所以两者都在这里 duplicate key,因此 keymap 的值由 keymap3 的值更新。