來複習一波,HashMap底層實現原理解析

2020-12-17 願編程是詩

前言

HashMa是Java中最常用的集合類框架,也是Java語言中非常典型的數據結構,同時也是我們需要掌握的數據結構,更重要的是進大廠面試必問之一。

數組特點

存儲區間是連續,且佔用內存嚴重,空間複雜也很大,時間複雜為O(1)。優點:是隨機讀取效率很高,原因數組是連續(隨機訪問性強,查找速度快)。缺點:插入和刪除數據效率低,因插入數據,這個位置後面的數據在內存中要往後移的,且大小固定不易動態擴展。鍊表特點

區間離散,佔用內存寬鬆,空間複雜度小,時間複雜度O(N)。優點:插入刪除速度快,內存利用率高,沒有大小固定,擴展靈活。缺點:不能隨機查找,每次都是從第一個開始遍歷(查詢效率低)。哈希表特點

以上數組和鍊表,大家都知道各自優缺點。那麼我們能不能把以上兩種結合一起使用,從而實現查詢效率高和插入刪除效率也高的數據結構呢?答案是可以滴,那就是哈希表可以滿足,接下來我們一起複習HashMap中的put()和get()方法實現原理。

HashMap的put()和get()的實現

1、map.put(k,v)實現原理

第一步首先將k,v封裝到Node對象當中(節點)。第二步它的底層會調用K的hashCode()方法得出hash值。第三步通過哈希表函數/哈希算法,將hash值轉換成數組的下標,下標位置上如果沒有任何元素,就把Node添加到這個位置上。如果說下標對應的位置上有鍊表。此時,就會拿著k和鍊表上每個節點的k進行equal。如果所有的equals方法返回都是false,那麼這個新的節點將被添加到鍊表的末尾。如其中有一個equals返回了true,那麼這個節點的value將會被覆蓋。

2、map.get(k)實現原理

第一步:先調用k的hashCode()方法得出哈希值,並通過哈希算法轉換成數組的下標。第二步:通過上一步哈希算法轉換成數組的下標之後,在通過數組下標快速定位到某個位置上。重點理解如果這個位置上什麼都沒有,則返回null。如果這個位置上有單向鍊表,那麼它就會拿著參數K和單向鍊表上的每一個節點的K進行equals,如果所有equals方法都返回false,則get方法返回null。如果其中一個節點的K和參數K進行equals返回true,那麼此時該節點的value就是我們要找的value了,get方法最終返回這個要找的value。

3、為何隨機增刪、查詢效率都很高的原因是?

原因:增刪是在鍊表上完成的,而查詢只需掃描部分,則效率高。

HashMap集合的key,會先後調用兩個方法,hashCode and equals方法,這這兩個方法都需要重寫。

4、為什麼放在hashMap集合key部分的元素需要重寫equals方法?

因為equals默認比較是兩個對象內存地址

HashMap集合的key特點:

5、HashMap總結

無序,不可重複為什麼是無序的?因為不一定掛到哪一個單向鍊表上的,因此加入順序和取出也不一樣。怎麼保持不可重複?使用equals方法來保證HashMap集合key不可重複,如key重複來,value就會覆蓋。存放在HashMap集合key部分的元素,其實就是存放在HashSet集合中,則HashSet集合也需要重寫equals和hashCode方法。hashmap集合的默認初始化容量為16,默認加載因子為0.75,也就是說這個默認加載因子是當hashMap集合底層數組的容量達到75%時,數組就開始擴容。hashmap集合初始化容量是2的陪數,為了達到散列均勻,提高hashmap集合的存取效率,

6、注意JDK8之後

JDK8之後,如果哈希表單向鍊表中元素超過8個,那麼單向鍊表這種數據結構會變成紅黑樹數據結構。當紅黑樹上的節點數量小於6個,會重新把紅黑樹變成單向鍊表數據結構。

問題:

如果O1和O2的hash值相同,就會存放到同一個單向鍊表上,

如果不同,但由於哈希算法執行結束之後轉換的數組下標可能相同,此時會發上「哈希碰撞」。

7、高頻面試題

HashMap的工作原理是什麼?HashMap中的「死鎖」是怎麼回事?HashMap中能put兩個相同key嗎?為什麼?HashMap中的鍵值可以為null嗎?原理?HashMap擴容機制?很感謝各位人才能看到這裡,如果需要大數據、Java教程可以關注我,私信發送「Java、Springboot、mysql」等相關術語,即可獲取更多教程。

熬夜不易,創作不易,各位的支持和認可,就是我創作的最大動力,我們下篇文章見!如排版或者哪裡寫得不夠好,歡迎評論區一起交流。

相關焦點

  • Java面試高頻考點:HashMap的底層原理
    作為一個Java開發工程師,在面試的過程中,最高頻被問到的一個問題就是:「請簡述一下HashMap的實現原理」,在日常開發中,大多數程式設計師只會使用,對於其實現細節,卻不了解,殊不知這是較基礎卻也最重要的知識點。這篇文章將向大家詳細解釋hashmap的底層到底做了哪些事情。
  • HashMap底層原理,你真的懂了嗎?
    JDK1.8之前的版本HashMap底層實現是數組+鍊表的,也稱之「散列表」。JDK1.8之後,HashMap底層實現已經不止是數組+鍊表了,而是數組+鍊表+紅黑樹實現。紅黑樹的目的是什麼,就是讓鍊表插入和查詢效率提升。
  • 高並發編程系列:ConcurrentHashMap的實現原理(JDK1.7和JDK1.8)
    HashMap、CurrentHashMap 的實現原理基本都是BAT面試必考內容,阿里P8架構師談:深入探討HashMap的底層結構、原理、擴容機制深入談過hashmap的實現原理以及在JDK 1.8的實現區別,今天主要談CurrentHashMap的實現原理,以及在JDK1.7和1.8的區別。
  • Java面試必問之Hashmap底層實現原理(JDK1.7)
    Hashmap底層實現原理(get\put\resize)Hashmap怎麼解決hash衝突?Hashmap是線程安全的嗎?構造方法首先看構造方法的源碼由以上源碼可知,Hashmap的初始容量默認是16, 底層存儲結構是數組(到這裡只能看出是數組, 其實還有鍊表,下邊看源碼解釋)。基本存儲單元是Entry,那Entry是什麼呢?我們接著看Entry相關源碼由Entry源碼可知,Entry是鍊表結構。
  • ConcurrentHashMap實現線程安全的底層原理
    項目中經常會有多個線程要訪問同一個數據,此時比較常用的辦法是用synchronize加鎖,CAS去進行安全的累加,去實現多線程場景下的安全的更新一個數據的效果,HashMap是用的比較多,可能就是多個線程同時讀寫一個HashMap,HashMap是線程不安全的,如果對整個map去synchronized
  • HashMap加載因子為何0.75,為何初始化值2的指數冪,底層解析
    大家有沒有看過hashmap的底層,java7版本是數組加鍊表1.8之後引入紅黑樹。性能提升百分之十到到百分之15左右。2.1 hashmap 結構是數組,每個數組裡面的結構是node(鍊表或紅黑樹),正常情況下,如果你想放數據到不同的位置,肯定會想到取餘數確定放在那個數據裡, 計算公式:hash % n,這個是十進位計算。
  • 教你用 Python 實現 HashMap 數據結構
    hashmap和hash算法究竟是什麼關係?hashmap有哪些參數,這些參數分別是做什麼用的?hashmap是線程安全的嗎?我們怎麼來維護hashmap的平衡呢?讓我們帶著疑問來看看hashmap的基本結構。
  • Open Clustering HashMap實現原理:ThreadLocalMap中HashMap實現原理的深度剖析
    為什麼我們會說HashMap不是基於數組+鍊表的方式實現的呢?其實這是大家的狹義理解導致的。真正的HashMap是廣義的概念,我們平常所說的HashMap都是只Java裡面的HashMap實現。這只是所有HashMap實現方法中的一種。廣義的HashMap從尋址方式上分為Open Addressing HashMap和Closed Addressing HashMap。
  • java中HashMap原理?面試?你是誰,你在哪?
    HashMap是基於hashing的原理,我們使用put(key, value)存儲對象到HashMap中,使用get(key)從HashMap中獲取對象。當我們給put()方法傳遞鍵和值時,我們先對鍵調用hashCode()方法,計算並返回的hashCode是用於找到Map數組的bucket位置來儲存Node 對象。
  • 從Java源碼來深度挖掘HashMap的實現原理
    HashMap定義說的專業一點,HashMap是常用的用於存儲key-value鍵值對數據的一個集合,底層是基於對Map的接口實現。HashMap底層結構table數組首先我們要知道,我們存在HashMap中的數據最終是存了什麼地方,就是如下的結構。
  • 告訴你 Dubbo 的底層原理,面試不再怕!
    前言平常我們在構建分布式系統的時候,一般都是基於 Dubbo 技術棧或者是 SpringCloud 技術棧來做。但是現在還是有不少公司沒有換成 SpringCloud 來做微服務的東西,還是基於 Dubbo,面試的時候不管是 SpringCloud 也好,Dubbo 也罷,基本上都會提到這兩個框架的底層原理。你想嘗試一下高級的職位,基本上跑不脫這個問題。OK,今兒我們就大概聊聊 Dubbo 的底層架構原理吧。
  • Java HashMap工作原理及實現
    你知道HashMap的工作原理嗎?你知道get和put的原理嗎?equals()和hashCode()的都有什麼作用?你知道hash的實現嗎?為什麼要這樣實現?如果HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦?
  • Java多線程:由淺入深看synchronized的底層實現原理
    淺聊synchronized的使用MDove:說起synchronized的底層實現原來,咱們先看看synchronized的倆種加鎖方式:1、某個對象實例內此作用域內的synchronized鎖 ,可以防止多個線程同時訪問這個對象的
  • HashMap容量為什麼必須是2的k次方
    而裡面關鍵的get、put、resize方法更是有過無數分析,今天主要分析一下哈希算法、容量為何選為2k這兩個點,雖然也有大量人分析過,但如果你看完我的分析絕對會讓你更深入理解原理,而不是面試的時候只能巴拉巴拉侃兩句,起碼讓你能侃三句。
  • 漫畫| Spring AOP的底層原理是什麼?
    >Spring的作用域有singleton、prototype、request、session和global session6、Spring AOP的底層原理是什麼Spring AOP的底層都是通過代理來實現的一種是基於JDK的動態代理一種是基於CgLIB的動態代理
  • 並發組件CountDownLatch的底層原理
    ,而不同的AQS實現的Sync組件是不一樣的。 countDown的整個過程如下圖所示:(大家可以跟著序號1-4步來理解)            throw new InterruptedException();        if (tryAcquireShared(arg) < 0)            doAcquireSharedInterruptibly(arg);    } 這個還是很熟悉,不就是ReentrantLock的加鎖代碼的底層原理麼
  • 詳解鎖原理,synchronized、volatile+cas底層實現
    當嘗試給資源加鎖卻被其他線程先鎖定時,不是阻塞等待而是循環再次加鎖在鎖常被短暫持有的場景下,線程阻塞掛起導致CPU上下文頻繁切換,這可用自旋鎖解決;但自旋期間它佔用CPU空轉,因此不適用長時間持有鎖的場景2 synchronized底層原理代碼使用synchronized加鎖,在編譯之後的字節碼是怎樣的呢
  • 3.HashMap源碼剖析
    一、 基本原理HashMap底層基於數組+鍊表的數據結構,當出現hash衝突的時候,就將衝突的節點掛在鍊表尾部