HashMap
HashMap也是我們使用非常多的Collection,它是基于哈希表的 Map 接口的實現,以key-value的形式存在。在HashMap中,key-value總是會當做一個整體來處理,系統會根據hash算法來來計算key-value的存儲位置,我們總是可以通過key快速地存、取value。
實際上HashMap是一個“鏈表散列”HashMap底層實現還是數組,只是數組的每一項都是一條鏈。
HashMap保存數據的過程
首先判斷key是否為null,若為null,則直接調用putForNullKey方法。若不為空則先計算key的hash值,然后根據hash值搜索在table數組中的索引位置,如果table數組在該位置處有元素,則通過比較是否存在相同的key,若存在則覆蓋原來key的value,否則將該元素保存在鏈頭(最先保存的元素放在鏈尾)。若table在該處沒有元素,則直接保存。
put方法流程
當我們調用put存值時,HashMap首先會調用K的hashCode方法,獲取哈希碼,通過哈希碼快速找到某個存放位置,這個位置可以被稱之為bucketIndex,通過hashCode的協定可以知道,如果hashCode不同,equals一定為false,如果hashCode相同,equals不一定為true。所以理論上,hashCode可能存在沖突的情況,有個專業名詞叫碰撞,當碰撞發生時,計算出的bucketIndex也是相同的,這時會取到bucketIndex位置已存儲的元素,最終通過equals來比較,equals方法就是哈希碼碰撞時才會執行的方法,所以前面說HashMap很少會用到equals。HashMap通過hashCode和equals最終判斷出K是否已存在,如果已存在,則使用新V值替換舊V值,并返回舊V值,如果不存在 ,則存放新的鍵值對<K, V>到bucketIndex位置。
hashCode 的常規協定
在 Java 應用程序執行期間,在同一對象上多次調用 hashCode 方法時,必須一致地返回相同的整數,
前提是對象上 equals 比較中所用的信息沒有被修改。
如果根據 equals(Object) 方法,兩個對象是相等的,
那么在兩個對象中的每個對象上調用 hashCode 方法都必須生成相同的整數結果。