筆者自語: 當有一個面試官問我NSDictionary底層實現原理,我平時開發的時候只是會用而已,哪裏知道它的內部實現原理呀,一臉懵逼的樣子,感受跟那個面試的人相差甚遠,如今有空來系統整理一下我本身對NSDictionary內部實現原理的理解,真的理解了對你只有好處沒有壞處,永遠不要說我會用就完了,那只是初級開發工程師的要求不是嗎?廢話很少說,但願各位引發重視。面試
一言以蔽之: 在OC中NSDictionary是使用hash表來實現key和value的映射和存儲的。算法
那麼問題來了什麼是hash表呢?數組
哈希表(hash表):又叫作散列表,是根據關鍵碼值(key value)而直接訪問的數據結構。也就是說它經過關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射叫作函數,存放記錄的數組叫作哈希表。數據結構
讀到此處咱們獲得一個關鍵信息:所謂哈希表就是一個數組,數組中每個元素稱爲一個箱子(bin),箱子中存放的是鍵值對。看一個示意圖就一目瞭然了:函數
hash表存儲過程簡單介紹:cdn
依此咱們得出結論: OC中的字典實際上是一個數組,數組中每個元素一樣爲一個鏈表實現的數組,也就是數組中套數組。對象
那麼對應在oc中字典是如何進行存儲的呢?blog
在oc中每個對象建立時,都默認生成一個hashCode,也就是通過hash算法生成的一串數字,當利用key去取字典中的value時,如果使用遍歷或者二分查找等方法,效率相對較低,因而出現了根據每個key生成的hashCode將鍵值對放到hasCode對應的數組中的指定位置,這樣當用key去取值時,便沒必要遍歷去獲取,既能夠根據hashCode直接取出。由於hashCode的值過大,或許通過取餘獲取一個較小的數字,假如是對999進行取餘運算,那麼獲得的結果始終處於0-999之間。可是,這樣作的弊端在於取餘所獲得的值,多是相同的,這樣可能致使徹底不相干的鍵值對被新的鍵值對(取餘後值key相等)所覆蓋,因而出現了數組中套鏈表實現的數組。這樣,key值取餘獲得值相等的鍵值對,都將保存在同一個鏈表數組中,當查找key對應的值時,首先獲取到該鏈表數組,而後遍歷數組,取正確的key所對應的值便可。開發
至此NSDictionary的底層原理算是基本上講透徹了,但願對看到者有必定的啓示做用,那麼筆者就心滿意足了。hash