前言
在實際應用中,很多時候我們map儲存的元素是不需要講究順序,key也不需要具備可比較性的。接下來我們就來了解一下雜湊表(hash table)。
1. 基本概念
這些資料由 key 和 value 組成,雜湊表底層是陣列,key 通過雜湊函式計算(o(1)級別的計算)後,得到陣列的索引,然後在陣列索引位置放入 value。如:
2. 雜湊衝突 (hash collision)
解決雜湊衝突的常見方法
開放位址法 (open addressing)
按照一定規則向其他位址探測,直到遇到空桶
(線性探測,乙個位置乙個位置地往下探測;平方探測,按照數的平方跳過進行探測)
再雜湊法 (re - hashing)
設計多個雜湊函式,把雜湊衝突的值在計算一次
鏈位址法 (separate chaining)
比如通過鍊錶將同一 index的元素串起來
2.1jdk 1.8 的雜湊衝突解決方案
鏈位址法
當紅黑樹節點數量少到一定程度時,又會轉為單向鍊錶
jdk1.8 中的雜湊表是使用鍊錶 + 紅黑樹解決雜湊衝突
思考:為什麼使用單向鍊錶?
3. 雜湊函式
雜湊表中雜湊函式的實現步驟大概如下:
3.1 如何生成 key 的雜湊值
不同種類的 key, 雜湊值的生成方式不一樣,但目標是一致的
盡量讓每個key的雜湊值是唯一的3.1.1. 整數盡量讓key的所有資訊參與運算
3.1.2. 浮點數
將儲存的二進位制格式轉為整數值(也就是說浮點數在計算機裡也有乙個對應的二進位制數,它也能轉化成相應的int型別的hashcode值)
3.1.3. long和double的雜湊值
》 和 ^ 的作用是?
3.1.3. 字串
關於31的**
3.1.4. 自定義物件
自定義物件本身是繼承自object方法的,它本身就實現了hashcode的方法,但是它是以位址值作為雜湊值的,所以即使是兩個物件的屬性值是一致的,但是該物件的hashcode的值也是不一致的。
所以在實際開發中,我們一般需要重寫hashcode的方法以達到我們的需求。
public
class
person
//計算出每個屬性的hash值,並把該物件看成乙個字串
@override
public
inthashcode()
}
比如我們把物件的屬性看成字串的組成,通過各個值運算後相加得到最終的hash值。這樣上面兩個物件對應的hash值就是相同的了。
除了重寫hashcode() 方法外,還需要重寫 equal() 方法 (hashmap的key 必須實現 hashcode, equals 方法)主要作用:hashcode() 主要是為了定位索引值,equals() 主要是為了解決hash衝突時的值覆蓋
@override
public
boolean
equals
(object obj)
存放在同一陣列的煉表列裡表示的是他們算出來的索引值是一樣的,但不能表示他們的hash值是一樣的,因為算出來的hash值還需要與陣列長度進行 & 運算;
hash值相同的變數不能代表是同乙個變數,因為他們是通過乙個hash演算法計算而來。(有可能他們型別不同,但是計算出來的hash值卻是相同的)hash值相同,索引值就是相同的;但索引值相同,hash值不一定是相同的
== 比較的是兩個變數的位址,equals 比較的是兩個變數的內容是否相等
public
static
void
main
(string[
] args)
假如我們沒有重寫hashcode和 equals 方法那麼我們得到 map的容量為3,因為object型別的hashcode方法比較的是位址,所以是兩個不同的person 物件,新增後map的容量為3
假如我們重寫equals方法,沒有重寫hashcode方法那麼我們map容量的值為2或3,因為兩個person的hash值雖然不一樣,但他們定位的索引值可能一樣,如果一樣的情況,我們又實現了equals的方法,那麼p2會覆蓋p1,則容量為2;如果是不一樣的情況,那麼兩個person的索引值自然不同,也就不存在覆蓋現象,那麼mpa的容量就為3.
假如我們重寫hashcode方法,沒有重寫equals方法那麼我們map容量的值為3, 因為重寫了hashcode後,兩個person物件的hash值是相同的,定位的索引值也是相同的,但是我們解決雜湊衝突時呼叫的equals()方法預設是通過位址比較的,由於位址不同,所以不會覆蓋,那麼map的容量為3.
兩個方法之間的聯絡自定義物件作為 key, 最好同時重寫 hashcode, equals方法 (hashcode是用來確定索引的位置的,equals是來解決hash衝突時的覆蓋問題)
資料結構 雜湊表
1.雜湊表的定義 元素的儲存位置和它的關鍵碼之間建立乙個確定的對應關係h,使得每個關鍵碼key和唯一的儲存位置h key 相對應。在查詢時,根據這個確定的對應關係找到給定值k的對映h k 若查詢集合中存在這個記錄,則必定在h k 的位置上,這種查詢技術稱為雜湊技術。採用雜湊技術將記錄儲存在一塊連續的...
資料結構 雜湊表
雜湊表的定義 雜湊表 hash table,也叫雜湊表 是根據關鍵碼值 key value 而直接進行訪問的資料結構。也就是說,它通過把 關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的 速度。這個對映函式叫做雜湊函式,存放 記錄的陣列叫做雜湊表。雜湊函式的析構方法 餘數法 取關鍵字被某個不大於雜...
資料結構 雜湊表
3 雜湊函式 數字分析法 根據關鍵碼在各個位上的分布情況,選取分布比較均勻的若干位組成雜湊位址。適用情況 能預先估計出全部關鍵碼的每一位上各種數字出現的頻度,不同的關鍵碼集合需要重新分析。4 雜湊函式 平方取中法 對關鍵碼平方後,按照雜湊表大小,取中間的若干位作為雜湊位址 平方後擷取 適用情況 實現...