Java基礎-理解雜湊與雜湊碼
阿新 • • 發佈:2019-02-16
1.從HashMap說起
我們知道Map以鍵值對的形式來儲存資料。有一點值得說明的是,如果要使用我們自己的類作為鍵,我們必須同時重寫hashCode() 和 equals()兩個方法。HashMap使用equals方法來判斷當前的鍵是否與表中的鍵相同。equals()方法需要滿足以下5個條件
- 自反性 x.equals(x) 一定返回true
- 對稱性 x.equals(y)返回true,則y.equals(x) 也返回true
- 傳遞性 x.equals(y)返回true,y.equals(z)返回true,則x.equals(y)返回true
- 一致性 如果物件中的資訊沒有改變,x.equals(y)要麼一直返回true,要麼一直返回false
- 對任何不是null的x,想x.equals(null)一定返回false
2.雜湊
雜湊的價值在於速度。
假如鍵沒有按照一定的順序進行儲存,那麼查詢的時候就只能按照順序進行線性查詢,然而,線性查詢是最慢的查詢方式。所以,將鍵值按照一定的順序排序,並且使用二分查詢能購有效的提升速度。雜湊在此之上,更近一步,他將鍵儲存在陣列中(陣列的查詢速度最快),用陣列來表示鍵的資訊,但是由於Map的容量是可變的,而陣列的容量是不變的。要解決這個問題,陣列中存的並不是鍵本身,而是鍵物件生成的一個數字,將其作為陣列的下標,這個數字就是雜湊碼。
而這種辦法所產生的問題就是下標重複。而我們的解決辦法就是配合equals來確定鍵值。
查詢的過程首先就是計算雜湊碼,然後用雜湊碼來查詢函式(下標),通常,我們的陣列中儲存的是值的list,因此,我們計算出雜湊碼之後,通過下表取到的對應部分的list,然後通過equals就可以快速找到鍵值。
3.HashCode
hashCode函式是用來生成雜湊碼的,我們看看Integer的計算方式(ps:我們自己的物件我們要選擇自己的方式)
public static int hashCode(int value) {
return value;
}
這裡不在多說,我們自己的類有自己的雜湊碼實現就好。
4. 以HashMap的get方法來說明
public V get(Object key) {
if (key == null) {
HashMapEntry<K, V> e = entryForNullKey;
return e == null ? null : e.value;
}
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return e.value;
}
}
return null;
}
- int hash = Collections.secondaryHash(key); 計算出雜湊碼
- HashMapEntry
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return e.value;
}
- 若地址相同,返回值,
- 若hash值相等且equals返回true,返回值
5.總結
不知道各位朋友看了這篇之後是否理解了雜湊和雜湊碼。還是原來就懂,被我這麼一頓bb,不懂了!!!