1. 程式人生 > 實用技巧 >看完這篇 HashMap,和麵試官扯皮就沒問題了

看完這篇 HashMap,和麵試官扯皮就沒問題了

HashMap 概述

如果你沒有時間細摳本文,可以直接看 HashMap 概述,能讓你對 HashMap 有個大致的瞭解

HashMap 是 Map 介面的實現,HashMap 允許空的 key-value 鍵值對,HashMap 被認為是 Hashtable 的增強版,HashMap 是一個非執行緒安全的容器,如果想構造執行緒安全的 Map 考慮使用 ConcurrentHashMap。HashMap 是無序的,因為 HashMap 無法保證內部儲存的鍵值對的有序性。

HashMap 的底層資料結構是陣列 + 連結串列的集合體,陣列在 HashMap 中又被稱為桶(bucket)。遍歷 HashMap 需要的時間損耗為 HashMap 例項桶的數量 + (key - value 對映) 的數量。因此,如果遍歷元素很重要的話,不要把初始容量設定的太高或者負載因子設定的太低。

HashMap 例項有兩個很重要的因素,初始容量和負載因子,初始容量指的就是 hash 表桶的數量,負載因子是一種衡量雜湊表填充程度的標準,當雜湊表中存在足夠數量的 entry,以至於超過了負載因子和當前容量,這個雜湊表會進行 rehash 操作,內部的資料結構重新 rebuilt。

注意 HashMap 不是執行緒安全的,如果多個執行緒同時影響了 HashMap ,並且至少一個執行緒修改了 HashMap 的結構,那麼必須對 HashMap 進行同步操作。可以使用 Collections.synchronizedMap(new HashMap) 來建立一個執行緒安全的 Map。

HashMap 會導致除了迭代器本身的 remove 外,外部 remove 方法都可能會導致 fail-fast 機制,因此儘量要用迭代器自己的 remove 方法。如果在迭代器建立的過程中修改了 map 的結構,就會丟擲 ConcurrentModificationException

異常。

下面就來聊一聊 HashMap 的細節問題。我們還是從面試題入手來分析 HashMap 。

HashMap 和 HashTable 的區別

我們上面介紹了一下 HashMap ,現在來介紹一下 HashTable

相同點

HashMap 和 HashTable 都是基於雜湊表實現的,其內部每個元素都是 key-value 鍵值對,HashMap 和 HashTable 都實現了 Map、Cloneable、Serializable 介面。

不同點

  • 父類不同:HashMap 繼承了 AbstractMap 類,而 HashTable 繼承了 Dictionary

  • 空值不同:HashMap 允許空的 key 和 value 值,HashTable 不允許空的 key 和 value 值。HashMap 會把 Null key 當做普通的 key 對待。不允許 null key 重複。


  • 執行緒安全性:HashMap 不是執行緒安全的,如果多個外部操作同時修改 HashMap 的資料結構比如 add 或者是 delete,必須進行同步操作,僅僅對 key 或者 value 的修改不是改變資料結構的操作。可以選擇構造執行緒安全的 Map 比如 Collections.synchronizedMap 或者是 ConcurrentHashMap。而 HashTable 本身就是執行緒安全的容器。

  • 效能方面:雖然 HashMap 和 HashTable 都是基於單連結串列的,但是 HashMap 進行 put 或者 get