HashMap是Java中一個非常重要的數據結構,它基于哈希表實現,可以在常數時間內完成查找、插入和刪除操作
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
這個哈希函數首先判斷鍵值是否為null,如果是null則返回0。如果不是null,則調用鍵值的hashCode()方法獲取其哈希碼,然后將哈希碼與其無符號右移16位后的值進行異或操作,得到最終的哈希碼。
static int indexFor(int h, int length) {
return h & (length-1);
}
這個方法使用按位與操作將哈希碼與數組長度減1進行與操作,得到的結果就是數組索引。由于數組長度是2的整數次冪,所以這個操作等價于對哈希碼取模,但是效率更高。
碰撞解決:當兩個不同的鍵值經過哈希函數計算得到相同的哈希碼時,就會發生碰撞。在HashMap中,采用鏈地址法來解決碰撞問題。每個數組元素都是一個鏈表,當發生碰撞時,新的鍵值對會被添加到對應索引的鏈表中。在查找、插入和刪除操作時,需要遍歷鏈表來處理碰撞。
負載因子和動態擴容:HashMap中有一個負載因子(load factor)參數,用于控制哈希表的裝載程度。當哈希表中的元素數量超過負載因子與哈希表大小的乘積時,哈希表會自動擴容。擴容時,哈希表的大小會翻倍,然后重新計算每個元素的哈希碼并映射到新的數組索引上。
總之,HashMap的hash算法原理主要包括哈希函數、哈希值與數組索引的映射、碰撞解決和負載因子與動態擴容等方面。通過這些技術,HashMap能夠在常數時間內完成查找、插入和刪除操作,從而提高了程序的性能。