Hashmap其實是一個數組和鏈表的結合體,利用數組來模擬一個個桶(相似於Bucket Sort)以快速存取不一樣hashCode的key,對於相同hashCode的不一樣key,再調用其equals方法從List中提取出和key所相對應的value。數組存儲的是鏈表,鏈表是爲了解決哈希衝突的。 java
每當hashMap擴容後,內部的每一個元素存放的位置都會發生變化(由於元素的最終位置是其hashCode對key空間長度取模而得),所以resize方法中又會調用transfer函數,用來從新分配內部的元素;這個過程成爲rehash,是十分消耗性能的,所以在可預知元素的個數的狀況下,通常應該避免使用缺省的initialCapacity,而是經過構造函數爲其指定一個值。例如咱們可能會想要將數據庫查詢所得1000條記錄以某個特定字段(好比ID)爲key緩存在hashMap中,爲了提升效率、避免rehash,能夠直接指定initialCapacity爲2048。
Fail-Fast機制:咱們知道java.util.HashMap不是線程安全的,所以若是在使用迭代器的過程當中有其餘線程修改了map,那麼將拋出ConcurrentModificationException,這就是所謂fail-fast策略。 數據庫
這一策略在源碼中的實現是經過modCount域,modCount顧名思義就是修改次數,對HashMap內容的修改都將增長這個值,那麼在迭代器初始化過程當中會將這個值賦給迭代器的expectedModCount。 數組
LinkedHashMap的實現與 HashMap 的不一樣之處在於,前者維護着一個運行於全部條目的雙重連接列表,增長了維護連接列表的開支,其性能要比 HashMap 稍遜一籌,不過有一點例外:LinkedHashMap的迭代所需時間與其的所包含的元素成比例;而HashMap 迭代時間極可能開支較大,由於它所須要的時間與其容量(分配給Key空間的長度)成比例。一言以蔽之,隨機存取用HashMap,順序存取或是遍歷用LinkedHashMap。 緩存
這種數據結構很適合構建 LRU 緩存。缺省狀況下,LinkedHashMap採起的更新策略是相似於隊列的FIFO,若是你想實現更復雜的更新邏輯好比LRU(最近最少使用)。 安全
JAVA中確實存在着與其密切相關的四種引用:強引用、軟引用、弱引用以及幻象引用。 數據結構
HashMap採用的是採用相似於強引用的強鍵來管理的,這意味着即便做爲key的對象已經不存在了(指沒有任何一個引用指向它),也仍然會保留在HashMap中,在某些狀況下(例如內存緩存)中,這些過時的條目可能會形成內存泄漏等問題。 函數
WeakHashMap弱引用特別適合如下對象:佔用大量內存,但經過垃圾回收功能回收之後很容易從新建立 性能
介於HashMap和WeakHashMap之中的是SoftHashMap,它所採用的軟引用的策略指的是,垃圾收集器並不像其收集弱可及的對象同樣儘可能地收集軟可及的對象,相反,它只在真正 「須要」 內存時才收集軟可及的對象。軟引用對於垃圾收集器來講是一種「睜一隻眼,閉一隻眼」方式。 spa
其實要比WeakHashMap更適合於實現緩存機制。遺憾的是,JAVA中並無實現相關的SoftHashMap類(Apache和Google提供了第三方的實現)