最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

HashMap原理的深入理解

 更新時間:2019年04月03日 09:53:34   作者:visant  
這篇文章主要介紹了對HashMap原理的理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

hashing(散列法或哈希法)的概念

散列法(Hashing)是一種將字符組成的字符串轉(zhuǎn)換為固定長度(一般是更短長度)的數(shù)值或索引值的方法,稱為散列法,也叫哈希法。由于通過更短的哈希值比用原始值進行數(shù)據(jù)庫搜索更快,這種方法一般用來在數(shù)據(jù)庫中建立索引并進行搜索,同時還用在各種解密算法中。

HashMap概念和底層結(jié)構(gòu)

HashMap是基于哈希表的Map接口的非同步實現(xiàn)。此實現(xiàn)提供所有可選的映射操作,并允許使用null值和null鍵。HashMap儲存的是鍵值對,HashMap很快。此類不保證映射的順序,特別是它不保證該順序恒久不變。

HashMap實際上是一個“鏈表散列”的數(shù)據(jù)結(jié)構(gòu),即數(shù)組和鏈表的結(jié)合體。

數(shù)組:存儲區(qū)間連續(xù),占用內(nèi)存嚴重,尋址容易,插入刪除困難;
鏈表:存儲區(qū)間離散,占用內(nèi)存比較寬松,尋址困難,插入刪除容易;
Hashmap綜合應用了這兩種數(shù)據(jù)結(jié)構(gòu),實現(xiàn)了尋址容易,插入刪除也容易。

hashMap的結(jié)構(gòu)示意圖如下:

HashMap的基本存儲原理以及存儲內(nèi)容的組成

基本原理:先聲明一個下標范圍比較大的數(shù)組來存儲元素。另外設計一個哈希函數(shù)(也叫做散列函數(shù))來獲得每一個元素的Key(關(guān)鍵字)的函數(shù)值(即數(shù)組下標,hash值)相對應,數(shù)組存儲的元素是一個Entry類,這個類有三個數(shù)據(jù)域,key、value(鍵值對),next(指向下一個Entry)。

例如, 第一個鍵值對A進來。通過計算其key的hash得到的index=0。記做:Entry[0] = A。
第二個鍵值對B,通過計算其index也等于0, HashMap會將B.next =A,Entry[0] =B,
第三個鍵值對 C,index也等于0,那么C.next = B,Entry[0] = C;這樣我們發(fā)現(xiàn)index=0的地方事實上存取了A,B,C三個鍵值對,它們通過next這個屬性鏈接在一起。我們可以將這個地方稱為桶。 對于不同的元素,可能計算出了相同的函數(shù)值,這樣就產(chǎn)生了“沖突”,這就需要解決沖突,“直接定址”與“解決沖突”是哈希表的兩大特點。

HashMap的工作原理以及存取方法過程

HashMap的工作原理 :HashMap是基于散列法(又稱哈希法hashing)的原理,使用put(key, value)存儲對象到HashMap中,使用get(key)從HashMap中獲取對象。當我們給put()方法傳遞鍵和值時,我們先對鍵調(diào)用hashCode()方法,返回的hashCode用于找到bucket(桶)位置來儲存Entry對象?!盚ashMap是在bucket中儲存鍵對象和值對象,作為Map.Entry。并不是僅僅只在bucket中存儲值。

HashMap具體的存取過程如下:
put鍵值對的方法的過程是:

  1. ①判斷鍵值對數(shù)組table[i]是否為空或為null,否則執(zhí)行resize()進行擴容;
  2. ②根據(jù)鍵值key計算hash值得到插入的數(shù)組索引i,如果table[i]==null,直接新建節(jié)點添加,轉(zhuǎn)向⑥,如果table[i]不為空,轉(zhuǎn)向③;
  3. ③判斷table[i]的首個元素是否和key一樣,如果相同直接覆蓋value,否則轉(zhuǎn)向④,這里的相同指的是hashCode以及equals;
  4. ④判斷table[i] 是否為treeNode,即table[i] 是否是紅黑樹,如果是紅黑樹,則直接在樹中插入鍵值對,否則轉(zhuǎn)向⑤;
  5. ⑤遍歷table[i],判斷鏈表長度是否大于8,大于8的話把鏈表轉(zhuǎn)換為紅黑樹,在紅黑樹中執(zhí)行插入操作,否則進行鏈表的插入操作;遍歷過程中若發(fā)現(xiàn)key已經(jīng)存在直接覆蓋value即可;
  6. ⑥插入成功后,判斷實際存在的鍵值對數(shù)量size是否超多了最大容量threshold,如果超過,進行擴容。

get值方法的過程是:

1、指定key 通過hash函數(shù)得到key的hash值
int hash=key.hashCode();

2、調(diào)用內(nèi)部方法 getNode(),得到桶號(一般都為hash值對桶數(shù)求模)
int index =hash%Entry[].length;

3、比較桶的內(nèi)部元素是否與key相等,若都不相等,則沒有找到。相等,則取出相等記錄的value。

4、如果得到 key 所在的桶的頭結(jié)點恰好是紅黑樹節(jié)點,就調(diào)用紅黑樹節(jié)點的 getTreeNode() 方法,否則就遍歷鏈表節(jié)點。getTreeNode 方法使通過調(diào)用樹形節(jié)點的 find()方法進行查找。由于之前添加時已經(jīng)保證這個樹是有序的,因此查找時基本就是折半查找,效率很高。

5、如果對比節(jié)點的哈希值和要查找的哈希值相等,就會判斷 key 是否相等,相等就直接返回;不相等就從子樹中遞歸查找。

HashMap中直接地址用hash函數(shù)生成;解決沖突,用比較函數(shù)解決。如果每個桶內(nèi)部只有一個元素,那么查找的時候只有一次比較。當許多桶內(nèi)沒有值時,許多查詢就會更快了(指查不到的時候)。

HashMap中的碰撞探測(collision detection)以及碰撞的解決方法

當兩個對象的hashcode相同時,它們的bucket位置相同,‘碰撞'會發(fā)生。因為HashMap使用LinkedList存儲對象,這個Entry(包含有鍵值對的Map.Entry對象)會存儲在LinkedList中。這兩個對象就算hashcode相同,但是它們可能并不相等。 那如何獲取這兩個對象的值呢?當我們調(diào)用get()方法,HashMap會使用鍵對象的hashcode找到bucket位置,遍歷LinkedList直到找到值對象。找到bucket位置之后,會調(diào)用keys.equals()方法去找到LinkedList中正確的節(jié)點,最終找到要找的值對象使用不可變的、聲明作final的對象,并且采用合適的equals()和hashCode()方法的話,將會減少碰撞的發(fā)生,提高效率。不可變性使得能夠緩存不同鍵的hashcode,這將提高整個獲取對象的速度,使用String,Interger這樣的wrapper類作為鍵是非常好的選擇。

如何重新調(diào)整HashMap的大小

“如果HashMap的大小超過了負載因子(load factor)定義的容量,怎么辦?”

默認的負載因子大小為0.75,也就是說,當一個map填滿了75%的bucket時候,和其它集合類(如ArrayList等)一樣,將會創(chuàng)建原來HashMap大小的兩倍的bucket數(shù)組,來重新調(diào)整map的大小,并將原來的對象放入新的bucket數(shù)組中。這個過程叫作rehashing,因為它調(diào)用hash方法找到新的bucket位置。

以上所述是小編給大家介紹的HashMap原理的理解詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • java處理圖片背景顏色的方法

    java處理圖片背景顏色的方法

    這篇文章主要為大家詳細介紹了java處理圖片背景顏色的方法,藍底寸照批量轉(zhuǎn)換為白底,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • SpringBoot從0到1整合銀聯(lián)無跳轉(zhuǎn)支付功能附源碼

    SpringBoot從0到1整合銀聯(lián)無跳轉(zhuǎn)支付功能附源碼

    這篇文章主要介紹了SpringBoot從0到1整合銀聯(lián)無跳轉(zhuǎn)功能支付附源碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • IntelliJ IDEA設置代碼的快捷編輯模板Live Templates

    IntelliJ IDEA設置代碼的快捷編輯模板Live Templates

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA設置代碼的快捷編輯模板Live Templates,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • jenkins+maven+svn自動部署和發(fā)布的詳細圖文教程

    jenkins+maven+svn自動部署和發(fā)布的詳細圖文教程

    Jenkins是一個開源的、可擴展的持續(xù)集成、交付、部署的基于web界面的平臺。這篇文章主要介紹了jenkins+maven+svn自動部署和發(fā)布的詳細圖文教程,需要的朋友可以參考下
    2020-09-09
  • Java利用for循環(huán)輸出空心菱形的實例代碼

    Java利用for循環(huán)輸出空心菱形的實例代碼

    這篇文章主要介紹了Java利用for循環(huán)輸出空心菱形的實例代碼,需要的朋友可以參考下
    2014-02-02
  • 一起來學習JAVA的運算符

    一起來學習JAVA的運算符

    這篇文章主要為大家詳細介紹了JAVA的運算符,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Mybatis 動態(tài)sql if 判讀條件等于一個數(shù)字的案例

    Mybatis 動態(tài)sql if 判讀條件等于一個數(shù)字的案例

    這篇文章主要介紹了Mybatis 動態(tài)sql if 判讀條件等于一個數(shù)字的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java Web過濾器詳解

    Java Web過濾器詳解

    這篇文章主要為大家詳細介紹了Java WEB過濾器的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java中的LinkedHashMap源碼分析

    Java中的LinkedHashMap源碼分析

    這篇文章主要介紹了Java中的LinkedHashMap源碼分析,LinkedHashMap是HashMap的子類,所以基本的操作與hashmap類似,不過呢,在插入、刪除、替換key-value對的時候,需要的朋友可以參考下
    2023-12-12
  • 解決IDEA Gradle構(gòu)建報錯''Cause: zip END header not found''

    解決IDEA Gradle構(gòu)建報錯''Cause: zip END header not found''

    這篇文章主要介紹了解決IDEA Gradle構(gòu)建報錯"Cause: zip END header not found"的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02

最新評論

抚顺县| 汝阳县| 江西省| 子长县| 平度市| 略阳县| 邓州市| 米易县| 浙江省| 库车县| 威宁| 蛟河市| 大名县| 隆化县| 精河县| 河西区| 洪洞县| 大厂| 甘洛县| 营口市| 福泉市| 迁安市| 运城市| 白城市| 隆尧县| 瓦房店市| 昂仁县| 常山县| 马龙县| 秦皇岛市| 郯城县| 琼海市| 台中县| 文登市| 麻城市| 大渡口区| 神池县| 富民县| 贵德县| 东山县| 广丰县|