在上一篇 Java 集合之LinkedList 咱們講了Collection的一個實現類LinkedList,是基於鏈表的實現,按原來打算是準備介紹HashSet,可是HashSet又與HashMap關係密切,因此此次仍是先介紹HashMap吧算法
首先須要注意的是HashMap不是Collection的實現 而是Map的實現,看下Map結構圖編程
父接口Map是用來存儲具備映射關係的數據:Key-value數組
Map中的key和value均可以是任何引用類型的數據bash
經常使用String類做爲Map的「鍵」post
key和value之間存在單向一對一的關係,即經過指定的key總能找到惟一的 肯定的value性能
照例咱們看看Map接口中聲明的方法spa
對應Collection3d
咱們看到Map中並無add addAll 方法 卻有了put putAll方法 put系列方法就表明了新增和修改的方法code
咱們在看看HashMap實現類中有哪些方法cdn
HashMap除了實現了Map的通常方法還多了許多方法 可能是服務於具體實現的
HaspMap實現較爲複雜,若一行行看源碼,確定比較吃力 ,咱們先從思想上把握它
HashMap是爲了存儲kay-value鍵值結構而服務的,咱們假想一個例子
考試的教室有100個座位, 那怎麼讓同窗們對號入座且儘可能分散呢(避免提早商量抄襲),
咱們先把座位進行編號。好比1到100 ,而後根據同窗的特徵信息(好比學號)計算出一個值 恰好一一對應到咱們的編號1到100,
同窗們沒法知道這個計算的方法,那麼同窗們就會盡可能分散 從而沒法提早商量了。
複製代碼
在上面咱們知道座位的編號至關於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,這種叫作頭插法,即每次新元素來時插入頭部。
能夠理解爲了原來座位有人了,新來的我搬個凳子過來和你用一個桌子,哈哈
這樣就完成了座位了分配且又根本的解決了座位重合的問題
就這樣每一個同窗都陸續就坐完畢,可是老師點名找「A」時,怎麼找呢,這就是查找方法get
最簡單的是根據hash方法算一遍
index=Hash(length,"A的學號")//length至關於座位數
複製代碼
獲得index=2,可是這時根據學號算出的index=2的位置有兩人,這怎麼辦?
也簡單 挨個遍歷一遍 覈對下具體學號就完事了。
hashMap是基於數組加鏈表的實現
這裏的hash算法是整個實現的核心,篇幅緣由暫且不表,待後續文章放出
鏈表頭部插入的優點在於:後加入的元素被查找的可能性更大,那麼遍歷鏈表時,查到的速度最快,性能損耗最少
還有個問題是 咱們看到數組長度 是隨着愈來愈大的 那麼動態擴容成了問題之重
喜歡本文的朋友們,歡迎長按下圖關注訂閱號個人編程筆記,收看更多精彩內容