1. 程式人生 > 實用技巧 >Map介面及其實現類

Map介面及其實現類

Map提供了一種對映關係,其中的元素是以鍵值對(key-value)的形式儲存的,能夠實現根據key快速查詢value;Map中的鍵值對以Entry型別的物件例項形式存在;

鍵(key值)不可重複,value值可以重複,一個value值可以和很多key值形成對應關係,每個鍵最多隻能對映到一個值。

Map及其實現類類圖關係如下:

HashMap

HashMap一般作為Map介面的主要實現類來使用,它的key和value允許為null,key值不允許重複,所以key值最多隻有一個null值,在原始碼中定義了

DEFAULT_INITIAL_CAPACITY = 1 << 4;//初始化預設值為1<<4,即16
static final int MAXIMUM_CAPACITY = 1 << 30//預設最大容量為1<<30
static final float DEFAULT_LOAD_FACTOR = 0.75f;//預設負載因子為0.75
static final int TREEIFY_THRESHOLD = 8;//桶的樹化閾值:即連結串列轉成紅黑樹的閾值,在儲存資料時,當連結串列長度 > 8時,則將連結串列轉換成紅黑樹
static final int UNTREEIFY_THRESHOLD = 6;//當在擴容(resize())時(此時HashMap的資料儲存位置會重新計算),在重新計算儲存位置後,當原有的紅黑樹內數量 < 6時,則將 紅黑樹轉換成連結串列
static final int MIN_TREEIFY_CAPACITY = 64;//最小樹化容量闕值,即 當雜湊表中的容量 > 該值時,才允許樹形化連結串列 (即 將連結串列 轉換成紅黑樹)否則,若桶內元素太多時,則直接擴容,而不是樹形化,為了避免進行擴容、樹形化選擇的衝突,這個值不應小於 4 * TREEIFY_THRESHOLD

HashMap底層實現在1.7之前為陣列加連結串列,即計算出每個Entry<K,V>物件對應的hash值,並把Entry物件放入對應的陣列下標中,如果發生了Hash碰撞,會使用鏈地址法,把新傳入的Entry物件設為頭用next指向連結串列中的下一個Entry。

在1.8之後變為陣列加連結串列加紅黑二叉樹,即為一個連結串列的長度如果大於TREEIFY_THRESHOLD 並且tab陣列的容量大於等於64時,連結串列會轉化為紅黑二叉樹。

預設擴容機制:如果當前容量大於陣列容量*預設負載因子則直接*2,預設長度為16,如果是通過HashMap(int initialCapacity)設定初始容量時,HashMap會自動計算出第一個大於該數的2的冪,並把這個值返回作為陣列的初始長度。

HashMap是執行緒不安全的,如果想使用執行緒安全的HashMap可以使用Collections工具類中的synchronizedMap()方法,這個方法會返回一個執行緒安全的Map類,實現上在呼叫map所有方法時,都對整個map進行同步。

HashMap的構造方法共有4個,可以指定HashMap的陣列長度(並不能),負載因子,還可以傳入一個Map<? extends K, ? extends V> m。

Hashtable

Hashtable底層是一個雜湊表,它是一個執行緒安全的集合,單執行緒集合,速度慢,Hashtable集合不能儲存null值,null鍵。Hashtable單執行緒場景下效能不如HashMap,多執行緒場景下效能不如ConcurrentHashMap。

Hashtable集合逐漸被HashMap集合取代,但是Hashtable的子類Properties依然沿用,Properties集合也是唯一一個和IO流相結合的集合。

LinkedHashMap
LinkedHashMap是一個有序的Map,它雖然增加了時間和空間上得開銷,但是通過維護一個運行於所有條目的雙向連結串列,LinkedHashMap得以做到有序,這點有點類似於LinkedHashSet。
LinkedHashMap的Key值和Value值都允許為空,但是多個key值為空會覆蓋。
LinkedHashMap通過在Entry中新增了Entry<K,V>before,Entry<K,V>after來保證了Entry插入順序的先後。
TreeMap
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, Serializable
TreeMap類似於TreeSet可以對存入其中的資料的Key進行自然排序或者根據其建立時所指定的Comparator進行排序,具體取決於它的構造方法。
TreeMap的構造方法:

// 預設建構函式。使用該建構函式,TreeMap中的元素按照自然排序進行排列。
TreeMap()

// 建立的TreeMap包含Map
TreeMap(Map<? extends K, ? extends V> copyFrom)

// 指定Tree的比較器
TreeMap(Comparator<? super K> comparator)

// 建立的TreeSet包含copyFrom
TreeMap(SortedMap<K, ? extends V> copyFrom)