Java集合之HashMap

麥克斯維發表於2019-01-12

回顧

在上一篇 Java 集合之LinkedList 我們講了Collection的一個實現類LinkedList,是基於連結串列的實現,按原來打算是準備介紹HashSet,但是HashSet又與HashMap關係密切,所以這次還是先介紹HashMap吧

首先需要注意的是HashMap不是Collection的實現 而是Map的實現,看下Map結構圖

Java集合之HashMap

父介面Map是用來儲存具有對映關係的資料:Key-value

Map中的key和value都可以是任何引用型別的資料

常用String類作為Map的“鍵”

key和value之間存在單向一對一的關係,即通過指定的key總能找到唯一的 確定的value

照例我們看看Map介面中宣告的方法

Java集合之HashMap

對應Collection

我們看到Map中並沒有add addAll 方法 卻有了put putAll方法 put系列方法就代表了新增和修改的方法

我們在看看HashMap實現類中有哪些方法

Java集合之HashMap

HashMap除了實現了Map的一般方法還多了許多方法 多是服務於具體實現的

HaspMap實現較為複雜,若一行行看原始碼,肯定比較吃力 ,我們先從思想上把握它

原理

1.HaspMap是什麼?

HashMap是為了儲存kay-value鍵值結構而服務的,我們假想一個例子

考試的教室有100個座位, 那怎麼讓同學們對號入座且儘量分散呢(避擴音前商量抄襲),
我們先把座位進行編號。比如1到100 ,然後根據同學的特徵資訊(比如學號)計算出一個值 剛好一一對應到我們的編號1到100,
同學們無法知道這個計算的方法,那麼同學們就會盡量分散 從而無法提前商量了。
複製程式碼

2.HashMap的實現原理是什麼呢?

put方法

在上面我們知道座位的編號相當於key,而每一個同學就是一個value,同學們入座完畢後,那麼這個key-value就完成了, 通過程式碼我們知道 座位是用陣列來實現的

Java集合之HashMap

陣列初始化時每個單元都是null, 當第一個同學A來了,我們根據一個hash演算法得出他的座位

index=Hash("A的學號")
複製程式碼

此時得出index=2 即應該在2號座位入座

Java集合之HashMap

把每個同學看作是一個Entry,就這樣 同學們相安無事的陸續就坐了。

慢著我們彷彿發現了問題,這個問題就在與這個Hash方法 這個hash方法怎麼實現呢?與他相關的引數只有同學麼?

當然不是,萬一教室不是隻有100個座位 而是有200個座位呢 那原來的計算方法就不管用了。 所以我們知道了 這個hash方法應該是這樣的

index=Hash(length,"A的學號")//length相當於座位數
複製程式碼

我們看另一個問題 當資料越來越多,萬一根據hash演算法得出的index是一樣的怎麼辦?總不能把原來的entry移除吧

答案是這裡每個Entry又是一個連結串列(可參見Java集合之LinkedList),若遇到重複的則把新來的放到連結串列的頭部

Java集合之HashMap

上圖entry1原本在index=2的位置 當entry6來了時 把entry6放到了連結串列的頭部 entry1放到連結串列的尾部 entry6的next指向entry1,這種叫做頭插法,即每次新元素來時插入頭部。

可以理解為了原來座位有人了,新來的我搬個凳子過來和你用一個桌子,哈哈

這樣就完成了座位了分配且又根本的解決了座位重合的問題

get方法

就這樣每個同學都陸續就坐完畢,但是老師點名找“A”時,怎麼找呢,這就是查詢方法get

最簡單的是根據hash方法算一遍

index=Hash(length,"A的學號")//length相當於座位數
複製程式碼

得到index=2,但是這時根據學號算出的index=2的位置有兩人,這怎麼辦?

也簡單 挨個遍歷一遍 核對下具體學號就完事了。

總結

hashMap是基於陣列加連結串列的實現

這裡的hash演算法是整個實現的核心,篇幅原因暫且不表,待後續文章放出

連結串列頭部插入的優勢在於:後加入的元素被查詢的可能性更大,那麼遍歷連結串列時,查到的速度最快,效能損耗最少

還有個問題是 我們看到陣列長度 是隨著越來越大的 那麼動態擴容成了問題之重

喜歡本文的朋友們,歡迎長按下圖關注訂閱號我的程式設計筆記,收看更多精彩內容

Java集合之HashMap

相關文章