1. 程式人生 > >NSDictionary底層實現原理

NSDictionary底層實現原理

www 保存 開放 個數 hash表 bin 使用 假設 html

一言以蔽之:在OC中NSDictionary是使用hash表來實現key和value的映射和存儲的。

那麽問題來了什麽是hash表呢?

哈希表(hash表): 又叫做散列表,是根據關鍵碼值(key value)而直接訪問的 數據結構 。也就是說它通過關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射叫做 函數 ,存放記錄的 數組 叫做 哈希表 。

讀到此處我們得到一個關鍵信息:所謂 哈希表就是一個數組 ,數組中每一個元素稱為一個箱子(bin),箱子中存放的是鍵值對。看一個示意圖就一目了然了:

技術分享圖片

hash表存儲過程簡單介紹:

  1. 根據key值計算出它的hash值h;
  2. 假設箱子的個數是n,那麽鍵值對應該放在第(h%n)個箱子中。
  3. 如果該箱子中已經有了鍵值對,就是用開放尋址法或者拉鏈法解決沖突。使用拉鏈法解決哈希沖突時,每個箱子其實是一個鏈表,屬於同一個箱子的所有鍵值對都會排列在鏈表中。

依此我們得出結論:OC中的字典其實是一個數組,數組中每一個元素同樣為一個鏈表實現的數組,也就是數組中套數組。

那麽對應在oc中字典是如何進行存儲的呢?

在oc中每一個對象創建時,都默認生成一個hashCode,也就是經過hash算法生成的一串數字,當利用key去取字典中的value時,若是使用遍歷或者二分查找等方法,效率相對較低,於是出現了根據每一個key生成的hashCode將鍵值對放到hasCode對應的數組中的指定位置,這樣當用key去取值時,便不必遍歷去獲取,既可以根據hashCode直接取出。因為hashCode的值過大,或許經過取余獲取一個較小的數字,假如是對999進行取余運算,那麽得到的結果始終處於0-999之間。但是,這樣做的弊端在於取余所得到的值,可能是相同的,這樣可能導致完全不相幹的鍵值對被新的鍵值對(取余後值key相等)所覆蓋,於是出現了數組中套鏈表實現的數組。這樣,key值取余得到值相等的鍵值對,都將保存在同一個鏈表數組中,當查找key對應的值時,首先獲取到該鏈表數組,然後遍歷數組,取正確的key所對應的值即可。

轉自:https://www.codercto.com/a/20469.html

NSDictionary底層實現原理