日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hashMap怎么解决hash冲突的

發布時間:2025/5/22 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hashMap怎么解决hash冲突的 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

學Java的都知道hashMap的底層是“鏈表散列”的數據結構也也可以說是hash表。在put的實話先根據key的hashcode重新計算hash值的,而我們又知道hash是一種算法。所以哈希碼并不是完全唯一的。

查看哈希碼百科:

http://kaigejava.com/article/detail/168

?

?

哈希表可以說就是數組鏈表,底層還是數組但是這個數組每一項就是一個鏈表

一:為什么說hashmap的put方法是根據key進行hashcode計算的呢?

查看源碼:

?

?

?

在查看hash方法,如下:

?

?

查看putVal方法:

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,

boolean evict) {

Node?[] tab; Node?p; int n, i;

if ((tab = table) == null || (n = tab.length) == 0)

n = (tab = resize()).length;

if ((p = tab[i = (n - 1) & hash]) == null)

tab[i] = newNode(hash, key, value, null);

else {

Node?e; K k;

if (p.hash == hash &&

((k = p.key) == key || (key != null && key.equals(k))))

e = p;

else if (p instanceof TreeNode)

e = ((TreeNode?)p).putTreeVal(this, tab, hash, key, value);

else {

for (int binCount = 0; ; ++binCount) {

if ((e = p.next) == null) {

p.next = newNode(hash, key, value, null);

if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st

treeifyBin(tab, hash);

break;

}

if (e.hash == hash &&

((k = e.key) == key || (key != null && key.equals(k))))

break;

p = e;

}

}

if (e != null) { // existing mapping for key

V oldValue = e.value;

if (!onlyIfAbsent || oldValue == null)

e.value = value;

afterNodeAccess(e);

return oldValue;

}

}

++modCount;

if (++size > threshold)

resize();

afterNodeInsertion(evict);

return null;

}

二:hashmap怎么解決key的hash值沖突問題的?

?

?

上圖是源碼截圖,說明:

1:初始化map的大小。默認是16

示例代碼:HashMap map = new HashMap();

2:如果tab為空,就newNode一個放到鏈表中

示例代碼:map.put("aa",1); 也就是圖-1測試代碼中的1

3:根據key算出的hash值如果存在,且key的值和map中已經存在的值equals了。所以就不處理。

如下圖:

?

測試代碼如圖-1測試代碼中的1和 2

4:如果p是TreeNode的子類進行putTreeValu

5:如果key的hash值和map中已經存在的key的hash相等且key不同的時候,如果數組該位置上沒有元素,就直接將該元素放到此數組中的該位置上。

如圖-1測試代碼 1和4中key的hesh值都為3104

圖-1測試代碼

?

?

在來看下Node這個內部類:

?

?

三:在來看看怎么get方法

?

?

?

說明:

1:如果鏈表中第一個值的hash值和需要獲取的key的hash值相等的話,就直接取出。

2:如果鏈表first.next !=null就循環查找鏈表中的key,知道查詢到key.equals(k) 取出對應的值。

查看源碼或許感覺不懂,那么畫圖來說明:

?

?

總結:

數據結構:哈希表可以說就是數組鏈表,底層還是數組但是這個數組每一項就是一個鏈表。

map的put方法:

1:new hashMap的時候初始化默認大小為16

2:當map.put("aa",1)的時候判斷map沒有值,就把aa算的hash值放到0X004的位置

3:當再次執行map.put("aa",1)的是計算aa的hash值為3104.此時在OX004的位置已經有數據了。進行判斷存在的key和新put的key是否相同。相同不處理,值覆蓋

4:執行map.put("aa",2)的時候key和已經存在的key相同就直接覆蓋value了

5:執行map.put(3104,"cc")的時候,key的hash值也為3104.此時數組中OX004已經存在數據,判斷key是否相同。發現3104和aa不相同【注:此時就發生了hash沖突】,那么就aa這個鏈表前面追加3104

6:執行map.put("bb","cc")。假設bb計算出的hash值是3105就存放在了OX005上。

其他依次類推

?

map的get方法:

當執行map.get("bb")的時候先計算出bb的hash值為3105在對應的位置(也就是0X005)取出第一個判斷值是不是bb如果是就直接取出value.

當執行map.get("aa")的時候先計算出aa的hash值為3104,去對應的位置取出判斷值(3104)不等于(aa)且還有next。就循環取出進行比較。

http://kaigejava.com/article/detail/168

轉載于:https://my.oschina.net/kaigejava/blog/1862070

總結

以上是生活随笔為你收集整理的hashMap怎么解决hash冲突的的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。