一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - HashMap原理的深入理解

HashMap原理的深入理解

2021-07-28 11:51visant Java教程

這篇文章主要介紹了對HashMap原理的理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

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

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

hashmap概念和底層結構

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

hashmap實際上是一個“鏈表散列”的數據結構,即數組和鏈表的結合體。

數組:存儲區間連續,占用內存嚴重,尋址容易,插入刪除困難;
鏈表:存儲區間離散,占用內存比較寬松,尋址困難,插入刪除容易;
hashmap綜合應用了這兩種數據結構,實現了尋址容易,插入刪除也容易。

hashmap的結構示意圖如下:

HashMap原理的深入理解

hashmap的基本存儲原理以及存儲內容的組成

基本原理:先聲明一個下標范圍比較大的數組來存儲元素。另外設計一個哈希函數(也叫做散列函數)來獲得每一個元素的key(關鍵字)的函數值(即數組下標,hash值)相對應,數組存儲的元素是一個entry類,這個類有三個數據域,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;這樣我們發現index=0的地方事實上存取了a,b,c三個鍵值對,它們通過next這個屬性鏈接在一起。我們可以將這個地方稱為桶。 對于不同的元素,可能計算出了相同的函數值,這樣就產生了“沖突”,這就需要解決沖突,“直接定址”與“解決沖突”是哈希表的兩大特點。

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

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

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

HashMap原理的深入理解

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

get值方法的過程是:

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

2、調用內部方法 getnode(),得到桶號(一般都為hash值對桶數求模)
int index =hash%entry[].length;

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

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

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

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

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

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

如何重新調整hashmap的大小

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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91国产在线第7页 | 香蕉eeww99国产精选播放 | 欧美一区二区三区综合色视频 | 好涨好爽好大视频免费 | 天天综合亚洲 | 国产成人精品日本亚洲网站 | 欧美日韩亚洲高清不卡一区二区三区 | 99在线视频精品费观看视 | 秋霞色 | 18国产精品白浆在线观看免费 | 99热这里只有精品久久免费 | 国产剧情一区二区三区 | 黄在线观看www免费看 | 欧美亚洲天堂 | 国产精品福利一区二区亚瑟 | 欧美亚洲国产精品久久第一页 | 日本免费观看95视频网站 | 99久久免费视频 | 免费一区二区视频 | 无人区在线观看免费国语完整版 | 免费看一级毛片 | 日本无卡视频 | 欧美黑人换爱交换乱理伦片 | 久久99热狠狠色AV蜜臀 | 国产欧美日韩在线播放 | 爱情岛论坛亚洲品质自拍视频 | 男女羞羞的视频 | 国产盗摄wc厕所撒尿视频 | 国产综合亚洲专区在线 | 亚洲精品第一国产综合高清 | 国产高清不卡码一区二区三区 | 亚洲 欧美 日韩 综合 | 超级碰在线视频 | 99精彩免费观看 | 久久婷婷五月免费综合色啪 | 免费欧美一级 | 涩涩五月天 | 青青草国产青春综合久久 | 69av导航 | 亚洲AV永久无码精品老司机蜜桃 | 免费观看成年人视频 |