數據結構——hash(hashmap源碼探究)

hash是什么?

hash也稱為散列,就是把任意長度的輸入,通過散列算法,變成固定長度的輸出,這個輸出值就是散列值。

舉例來說明一下什么是hash:

假設我們要把1~12存入到一個大小是5的hash表中,我們就是用index=number%5的公式去計算索引存入數據

hash是一個神奇的數據結構,可以以接近O(1)的時間復雜度去進行查詢

但是很快我們就會發現一個問題,就是相同的余數的值儲存在同一個索引下,這樣就會造成一個問題,比如我查詢8是否存儲在結構中,我們能直接訪問array[3]這個位置,里面存儲8,會返回給我們的一個true,然后如果我們想要查詢13是否存在該結構中,還是會去array[3]中查找,發現里面沒存有數據13,返回false

如何解決hash沖突?

首先,先來說一下哈希沖突,哈希沖突(Hash Collision)是指在使用哈希表存儲數據時,兩個或多個不同的鍵(Key)被哈希函數映射到同一個位置的情況。這種情況會導致數據的存儲和查找變得復雜,因此需要采取一些措施來解決哈希沖突。

解決hash沖突的方法:

1.拉鏈法:

鏈地址法是一種處理哈希沖突的方法,它是將所有散列到同一個地址的數據項存儲在一個單鏈表中。這樣,當查找某個數據項時,只需要在對應的鏈表中進行搜索即可。例如,HashMap 在解決存儲對象存在 hash 沖突的問題時,采用的就是鏈地址法,將相同 hash 值的對象以鏈表的形式進行存儲。

2.再hash法

在發生沖突的時候,再用另一個哈希函數算出哈希值,直到算出的哈希值不同為止。

3.線性探測

就是發生hash沖突時,往后面繼續去找空的地方,找到后把沖突的值放到空的散列值的里面。

hashmap源碼

Ctrl+鼠標左鍵點進去

先來看一下hash這個方法

定義了一個h,如果key==null那么就返回0作為hash值,如果不等于null,那么首先把h無符號右移16位相當于保留了原哈希碼的高16位,并將它們放在低16位的位置(同時丟棄了原始的低16位)。然后,這個右移后的值與原始的哈希碼進行異或操作。異或操作的一個特性是,任何數與0異或都保持不變,而與自身異或則結果為0。這種變換有助于將哈希碼的不同部分混合在一起,從而增加哈希值的分布范圍,減少哈希沖突的可能性。這個稱之為一次擾動,每運算一次就算作一次擾動,就是為了讓hash碼的每一位都參與運算并減少沖突。

hash這個函數就是給一個對象經過一個算法處理返回一串數字作為hash碼。

然后我們回過來看putVal函數

首先是判斷table是否為空;如果是空的話,先進行一個初始化

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)//如果數組中這個位置是空的,那么直接創建一個新的點把key,hash,value裝進去tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k)))) //先判斷我們取得的hash值和p的這個hash值是不是一樣如果一樣再開始判定key是不是一樣,判斷key相等的時候先判斷兩個key==,再判斷兩個key的值是不是一樣,如果一樣就令e=pe = p;else if (p instanceof TreeNode)//如果是樹結點就把樹結點按照樹結點的方式傳上去e = ((TreeNode<K,V>)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 1sttreeifyBin(tab, hash);break;}//一旦發現有相等的就直接跳出循環if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}//如果e不是空的,那就直接把這個值賦給老的,就是說當兩次put操作的key相等的時候后面put的值會覆蓋前面put的值if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;
}

1.如果hashmap是空的話,也就是它內部的table數組是null,在添加第一個元素的時候會進行初始化,為table分配內存空間,設置初始容量為16,和加載因子0.75

2.對要插入的鍵,計算hash值,拿到hash值之后使用hash值得與table數組的長度來確定該鍵的存儲位置,萬一出現了產生相同的hash值的情況下,hashmap采用鏈表或紅黑樹(鏈表大于8的時候用紅黑樹)。如果該桶中沒有元素就直接創建一個新的結點,如果不是空就遍歷鏈表或者紅黑樹,查找是否存在相同的鍵,存在相同的鍵就用新的鍵代替舊的鍵,如果不存在就將新的結點添加到末尾,(紅黑樹就按紅黑樹規則插入)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/45469.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/45469.shtml
英文地址,請注明出處:http://en.pswp.cn/web/45469.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

礦產資源潛力預測不確定性評價

研究目的&#xff1a; 不確定性評估&#xff1a; 到底什么叫不確定性&#xff0c;簡單來說就是某區域內的礦產資源量&#xff0c;并不確定到底有多少&#xff0c;你需要給出一個評估或者分布。 研究方法&#xff1a; 1.以模糊集來表示某些量&#xff1a; 關于什么是模糊集&am…

信通院全景圖發布 比瓴科技領跑軟件供應鏈安全,多領域覆蓋數字安全服務

近日&#xff0c;中國信息通信研究院在2024全球數字經濟大會—數字安全生態建設專題論壇正式發布首期《數字安全護航技術能力全景圖》&#xff08;以下簡稱全景圖&#xff09;。 比瓴科技入選軟件供應鏈安全賽道“開發流程安全管控、交互式安全測試、靜態安全測試、軟件成分分…

智慧水利:邁向水資源管理的新時代,結合物聯網、云計算等先進技術,闡述智慧水利解決方案在提升水災害防控能力、優化水資源配置中的關鍵作用

本文關鍵詞&#xff1a;智慧水利、智慧水利工程、智慧水利發展前景、智慧水利技術、智慧水利信息化系統、智慧水利解決方案、數字水利和智慧水利、數字水利工程、數字水利建設、數字水利概念、人水和協、智慧水庫、智慧水庫管理平臺、智慧水庫建設方案、智慧水庫解決方案、智慧…

數據分析——numpy教程

1.NumPy&#xff1a; 是Python的一個開源的數值計算庫。可以用來存儲和處理大型矩陣&#xff0c;比python自身的嵌套列表結構要高效&#xff0c;支持大量的維度數組與矩陣運算&#xff0c;此外也針對數組運算提供大量的數學函數庫&#xff0c;包括數學、邏輯、形狀操作、排序、…

前端數據加密,后端java解密

在前端對數據進行加密后&#xff0c;通常會使用一些加密算法和技術&#xff0c;如AES&#xff08;Advanced Encryption Standard&#xff09;進行數據加密。然后&#xff0c;將加密后的數據發送到后端。后端接收到加密數據后&#xff0c;使用Java語言進行解密。 以下是一個簡單…

MKS電源管理軟件OPTIMA RPDG DCG系列RF Elit600系列

MKS電源管理軟件OPTIMA RPDG DCG系列RF Elit600系列

數據結構——考研筆記(三)線性表之單鏈表

文章目錄 2.3 單鏈表2.3.1 知識總覽2.3.2 什么是單鏈表2.3.3 不帶頭結點的單鏈表2.3.4 帶頭結點的單鏈表2.3.5 不帶頭結點 VS 帶頭結點2.3.6 知識回顧與重要考點2.3.7 單鏈表的插入和刪除2.3.7.1 按位序插入&#xff08;帶頭結點&#xff09;2.3.7.2 按位序插入&#xff08;不帶…

spring事務 @Transactional

文章目錄 1. 簡介1.1 什么是事務1.2 什么是Spring事務管理1.3 Transactional注解的作用 2. Transactional注解的使用2.1 如何在Spring中使用Transactional2.2 Transactional的屬性配置 3. Transactional的工作原理3.1 Spring如何管理事務3.2 Transactional的底層實現 4. Transa…

數學建模·灰色關聯度

灰色關聯分析 基本原理 灰色關聯分析可以確定一個系統中哪些因素是主要因素&#xff0c;哪些是次要因素&#xff1b; 灰色關聯分析也可以用于綜合評價&#xff0c;但是由于數據預處理的方式不同&#xff0c;導致結果 有較大出入 &#xff0c;故一般不采用 具體步驟 數據預處理…

wps批量刪除空白單元格

目錄 原始數據1.按ctrlg鍵2.選擇“空值”&#xff0c;點擊“定位”3. 右擊&#xff0c;刪除單元格修改后的數據 原始數據 1.按ctrlg鍵 2.選擇“空值”&#xff0c;點擊“定位” 如圖所示&#xff0c;空值已被選中 3. 右擊&#xff0c;刪除單元格 修改后的數據

微軟Office PLUS辦公插件下載安裝指南

微軟OfficePLUS插件下載安裝指南 簡介&#xff1a; OfficePLUS微軟官方出品的Office插件 &#xff0c;OfficePLUS擁有30萬高質量模板素材&#xff0c;能幫助Word、Excel、Powerpoint、PDF等多種辦公軟件提升效率&#xff0c;具有智能化、模板質量高、運行快、穩定性強等優點。…

抽象工廠模式與工廠方法(簡單工廠)的區別

在軟件開發中&#xff0c;簡單工廠模式和工廠方法模式是兩種常用的創建型設計模式。盡管它們都用于創建對象&#xff0c;但它們的實現方式和應用場景有所不同。本文將詳細探討這兩種模式的區別&#xff0c;幫助你更好地理解和應用它們。 簡單工廠模式 簡單工廠模式&#xff0…

昇思25天學習打卡營第11天|RNN實現情感分類

概述 情感分類是自然語言處理中的經典任務&#xff0c;是典型的分類問題。本節使用MindSpore實現一個基于RNN網絡的情感分類模型&#xff0c;實現如下的效果&#xff1a; 輸入: This film is terrible 正確標簽: Negative 預測標簽: Negative輸入: This film is great 正確標…

Mongodb復合索引

學習mongodb&#xff0c;體會mongodb的每一個使用細節&#xff0c;歡迎閱讀威贊的文章。這是威贊發布的第90篇mongodb技術文章&#xff0c;歡迎瀏覽本專欄威贊發布的其他文章。如果您認為我的文章對您有幫助或者解決您的問題&#xff0c;歡迎在文章下面點個贊&#xff0c;或者關…

【計算機畢業設計】002基于weixin小程序家庭記賬本

&#x1f64a;作者簡介&#xff1a;擁有多年開發工作經驗&#xff0c;分享技術代碼幫助學生學習&#xff0c;獨立完成自己的項目或者畢業設計。 代碼可以私聊博主獲取。&#x1f339;贈送計算機畢業設計600個選題excel文件&#xff0c;幫助大學選題。贈送開題報告模板&#xff…

【實戰:python-Django發送郵件-短信-釘釘通知】

一 Python發送郵件 1.1 使用SMTP模塊發送郵件 import smtplib from email.mime.text import MIMEText from email.header import Headermsg_from 306334678qq.com # 發送方郵箱 passwd luzdikipwhjjbibf # 填入發送方郵箱的授權碼(填入自己的授權碼&#xff0c;相當于郵箱…

鴻蒙語言基礎類庫:【@ohos.uitest (UiTest)】 測試

UiTest UiTest提供模擬UI操作的能力&#xff0c;供開發者在測試場景使用&#xff0c;主要支持如點擊、雙擊、長按、滑動等UI操作能力。 該模塊提供以下功能&#xff1a; [By]&#xff1a;提供控件特征描述能力&#xff0c;用于控件篩選匹配查找。[UiComponent]&#xff1a;代…

實驗四:圖像的銳化處理

目錄 一、實驗目的 二、實驗原理 1. 拉普拉斯算子 2. Sobel算子 3. 模板大小對濾波的影響 三、實驗內容 四、源程序和結果 (1) 主程序(matlab) (2) 函數GrayscaleFilter (3) 函數MatrixAbs 五、結果分析 1. 拉普拉斯濾波 2. Sobel濾波 3. 不同大小模板的濾波…

單點登陸思路及流程

單點登錄&#xff08;Single Sign-On&#xff0c;簡稱SSO&#xff09;是一種流行的身份驗證和授權機制&#xff0c;允許用戶通過一次登錄獲得對多個應用程序或系統的訪問權限。實現單點登錄可以提高用戶體驗、簡化用戶管理和減少密碼重復輸入等問題。下面是一種常見的單點登錄實…

昇思25天學習打卡營第7天 | 基于MindSpore的GPT2文本摘要

本次打卡基于gpt2的文本摘要 數據加載及預處理 from mindnlp.utils import http_get# download dataset url https://download.mindspore.cn/toolkits/mindnlp/dataset/text_generation/nlpcc2017/train_with_summ.txt path http_get(url, ./)from mindspore.dataset impor…