回顧
在上一篇 Java 集合之LinkedList 我們講了Collection的一個實現類LinkedList,是基於連結串列的實現,按原來打算是準備介紹HashSet,但是HashSet又與HashMap關係密切,所以這次還是先介紹HashMap吧
首先需要注意的是HashMap不是Collection的實現 而是Map的實現,看下Map結構圖
父介面Map是用來儲存具有對映關係的資料:Key-value
Map中的key和value都可以是任何引用型別的資料
常用String類作為Map的“鍵”
key和value之間存在單向一對一的關係,即通過指定的key總能找到唯一的 確定的value
照例我們看看Map介面中宣告的方法
對應Collection
我們看到Map中並沒有add addAll 方法 卻有了put putAll方法 put系列方法就代表了新增和修改的方法
我們在看看HashMap實現類中有哪些方法
HashMap除了實現了Map的一般方法還多了許多方法 多是服務於具體實現的
HaspMap實現較為複雜,若一行行看原始碼,肯定比較吃力 ,我們先從思想上把握它
原理
1.HaspMap是什麼?
HashMap是為了儲存kay-value鍵值結構而服務的,我們假想一個例子
考試的教室有100個座位, 那怎麼讓同學們對號入座且儘量分散呢(避擴音前商量抄襲),
我們先把座位進行編號。比如1到100 ,然後根據同學的特徵資訊(比如學號)計算出一個值 剛好一一對應到我們的編號1到100,
同學們無法知道這個計算的方法,那麼同學們就會盡量分散 從而無法提前商量了。
複製程式碼
2.HashMap的實現原理是什麼呢?
put方法
在上面我們知道座位的編號相當於key,而每一個同學就是一個value,同學們入座完畢後,那麼這個key-value就完成了, 通過程式碼我們知道 座位是用陣列來實現的
陣列初始化時每個單元都是null, 當第一個同學A來了,我們根據一個hash演算法得出他的座位
index=Hash("A的學號")
複製程式碼
此時得出index=2 即應該在2號座位入座
把每個同學看作是一個Entry,就這樣 同學們相安無事的陸續就坐了。
慢著我們彷彿發現了問題,這個問題就在與這個Hash方法 這個hash方法怎麼實現呢?與他相關的引數只有同學麼?
當然不是,萬一教室不是隻有100個座位 而是有200個座位呢 那原來的計算方法就不管用了。 所以我們知道了 這個hash方法應該是這樣的
index=Hash(length,"A的學號")//length相當於座位數
複製程式碼
我們看另一個問題 當資料越來越多,萬一根據hash演算法得出的index是一樣的怎麼辦?總不能把原來的entry移除吧
答案是這裡每個Entry又是一個連結串列(可參見Java集合之LinkedList),若遇到重複的則把新來的放到連結串列的頭部
上圖entry1原本在index=2的位置 當entry6來了時 把entry6放到了連結串列的頭部 entry1放到連結串列的尾部 entry6的next指向entry1,這種叫做頭插法,即每次新元素來時插入頭部。
可以理解為了原來座位有人了,新來的我搬個凳子過來和你用一個桌子,哈哈
這樣就完成了座位了分配且又根本的解決了座位重合的問題
get方法
就這樣每個同學都陸續就坐完畢,但是老師點名找“A”時,怎麼找呢,這就是查詢方法get
最簡單的是根據hash方法算一遍
index=Hash(length,"A的學號")//length相當於座位數
複製程式碼
得到index=2,但是這時根據學號算出的index=2的位置有兩人,這怎麼辦?
也簡單 挨個遍歷一遍 核對下具體學號就完事了。
總結
hashMap是基於陣列加連結串列的實現
這裡的hash演算法是整個實現的核心,篇幅原因暫且不表,待後續文章放出
連結串列頭部插入的優勢在於:後加入的元素被查詢的可能性更大,那麼遍歷連結串列時,查到的速度最快,效能損耗最少
還有個問題是 我們看到陣列長度 是隨著越來越大的 那麼動態擴容成了問題之重
喜歡本文的朋友們,歡迎長按下圖關注訂閱號我的程式設計筆記,收看更多精彩內容