我很困惑,当地图遇到重复的密钥时 - 它进入同一个桶,所以检查相同的密钥并替换为新值。
当插入具有相同存储桶的不同密钥时会发生什么。
是否检查密钥以及密钥存储在何处?
答案 0 :(得分:2)
我假设你在谈论HashMap
。我们来看看source:
386 public V put(K key, V value) {
387 if (key == null)
388 return putForNullKey(value);
389 int hash = hash(key.hashCode());
390 int i = indexFor(hash, table.length);
391 for (Entry<K,V> e = table[i]; e != null; e = e.next) {
392 Object k;
393 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
394 V oldValue = e.value;
395 e.value = value;
396 e.recordAccess(this);
397 return oldValue;
398 }
399 }
400
401 modCount++;
402 addEntry(hash, key, value, i);
403 return null;
404 }
所以这里发生的是put()
方法哈希密钥并访问相应的存储桶。然后它循环遍历那里包含的条目 1 ,如果它找到一个条目,其键equal
是给定的密钥,它会用给定的值替换该条目的值,即:
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
如果没有找到这样的条目,我们通常只是在桶中添加一个新条目,即:
modCount++;
addEntry(hash, key, value, i);
return null;
1 Entry
是包含键值对的类。
答案 1 :(得分:1)
地图不允许重复键。如果插入了具有相同键的元素,则旧值将替换为新值。
例如:说我的地图如下:
Key Value Bucket
A Val1 1
B Val2 2
C Val3 1
铲斗结构:
Bucket 1 : A -> C
Bucket 2 : B
当有人试图输入另一个元素(C,Val6)时,其中C是键;然后插入后的地图结构如下:
Key Value Bucket
A Val1 1
B Val2 2
C Val6 1
因此,Value将替换为Map。
铲斗结构:
Bucket 1 : A -> C
Bucket 2 : B
现在解决问题的第二部分:当在同一个桶中输入具有相同值的不同密钥时,它只是添加到桶中(内部每个桶可能类似于ArrayList,其中元素在末尾添加清单)。
例如:让我们假设我们将以下对(D,Val 7)添加到上面的Map中,并假设Key D映射到bucket 1.然后插入后的地图结构如下:
Key Value Bucket
A Val1 1
B Val2 2
C Val6 1
D Val7 1
铲斗结构:
Bucket 1 : A -> C -> D
Bucket 2 : B
答案 2 :(得分:0)
输入重复键时,它只是用新值替换上一个键的值。当一个不同的密钥输入到同一个桶中时,它首先检查这是否是重复的,如果不是,则它会添加密钥及其相应的值。
答案 3 :(得分:0)
HashMap
“bucket”是一个链接列表。列表的每个元素都包含键,值,键的哈希以及指向列表中下一个元素的指针。
因此,当发生哈希冲突时,哈希表会迭代桶中的每个条目。它将条目哈希与插入密钥哈希以及插入密钥的条目密钥进行比较。如果它们都相等,则替换该值。如果它在没有匹配的情况下通过整个存储桶,则会向存储桶添加一个条目。