Android原生的數(shù)據(jù)結(jié)構(gòu)

HashMap

HashMap內(nèi)部是使用一個默認(rèn)容量為16的數(shù)組來存儲數(shù)據(jù)的。
數(shù)組中每一個元素卻又是一個鏈表的頭結(jié)點(diǎn)。
HashMap內(nèi)部存儲結(jié)構(gòu)是使用哈希表的拉鏈結(jié)構(gòu)(數(shù)組+鏈表)
每一個結(jié)點(diǎn)都是Entry類型
Entry存儲的內(nèi)容有key、value、hash值、和next下一個Entry
Entry數(shù)據(jù)是按什么規(guī)則進(jìn)行存儲的呢?
通過計算元素key的hash值,然后對HashMap中數(shù)組長度取余得到該元素存儲的位置,計算公式為hash(key)%len,
如果有多個元素key的hash值相同的話,后一個元素并不會覆蓋上一個元素,而是采取鏈表的方式,把之后加進(jìn)來的元素加入鏈表末尾

重點(diǎn)

HashMap中默認(rèn)的存儲大小就是一個容量為16的數(shù)組,
所以當(dāng)我們創(chuàng)建出一個HashMap對象時,即使里面沒有任何元素,也要分別一塊內(nèi)存空間給它,
而且,我們再不斷的向HashMap里put數(shù)據(jù)時,當(dāng)達(dá)到一定的容量限制時(這個容量滿足這樣的一個關(guān)系時候?qū)U(kuò)容:HashMap中的數(shù)據(jù)量>容量加載因子,而HashMap中默認(rèn)的加載因子是0.75),HashMap的空間將會擴(kuò)大,而且擴(kuò)大后新的空間一定是原來的2倍
那么HashMap要存儲完這些數(shù)據(jù)將要不斷的擴(kuò)容,而且在此過程中也需要不斷的做hash運(yùn)算,這將對我們的內(nèi)存空間造成很大消耗和浪費(fèi),而且
HashMap獲取數(shù)據(jù)是通過遍歷Entry[]數(shù)組來得到對應(yīng)的元素,在數(shù)據(jù)量很大時候會比較慢,所以在Android中,HashMap是比較費(fèi)內(nèi)存的

SparseArray

-SparseArray比HashMap更省內(nèi)存,在某些條件下性能更好,主要是因?yàn)樗?strong>避免了對key的自動裝箱(int轉(zhuǎn)為Integer類型),它內(nèi)部則是通過兩個數(shù)組來進(jìn)行數(shù)據(jù)存儲的,一個存儲key,另外一個存儲value,為了優(yōu)化性能,它內(nèi)部對數(shù)據(jù)還采取了壓縮的方式來表示稀疏數(shù)組的數(shù)據(jù),從而節(jié)約內(nèi)存空間,我們從源碼中可以看到key和value分別是用數(shù)組表示
SparseArray只能存儲key為int類型的數(shù)據(jù),同時,SparseArray在存儲和讀取數(shù)據(jù)時候,使用的是二分查找法
在put添加數(shù)據(jù)的時候,會使用二分查找法和之前的key比較當(dāng)前我們添加的元素的key的大小,然后按照從小到大的順序排列好,所以,SparseArray存儲的元素都是按元素的key值從小到大排列好的。
在獲取數(shù)據(jù)的時候,也是使用二分查找法判斷元素的位置,所以,在獲取數(shù)據(jù)的時候非???,比HashMap快的多,因?yàn)镠ashMap獲取數(shù)據(jù)是通過遍歷Entry[]數(shù)組來得到對應(yīng)的元素。
方法

Put get remove delete 獲取對應(yīng)的key keyat valueat
SparseArray性能比較好,但是由于其添加、查找、刪除數(shù)據(jù)都需要先進(jìn)行一次二分查找,所以在數(shù)據(jù)量大的情況下性能并不明顯,將降低至少50%。
滿足下面兩個條件我們可以使用SparseArray代替HashMap:
? 數(shù)據(jù)量不大,最好在千級以內(nèi)
? key必須為int類型,這中情況下的HashMap可以用SparseArray代替:

  1. HashMap<Integer, Object> map = new HashMap<>();
  2. 用SparseArray代替:
  3. SparseArray<Object> array = new SparseArray<>();

ArrayMap

一個<key,value>映射的[數(shù)據(jù)結(jié)構(gòu)]
內(nèi)部是使用兩個數(shù)組進(jìn)行數(shù)據(jù)存儲,一個數(shù)組記錄key的hash值,另外一個數(shù)組記錄Value值,它和SparseArray一樣,也會對key使用二分法進(jìn)行從小到大排序,在添加、刪除、查找數(shù)據(jù)的時候都是先使用二分查找法得到相應(yīng)的index,然后通過index來進(jìn)行添加、查找、刪除等操作

ArrayMap****應(yīng)用場景
數(shù)據(jù)量不大,最好在千級以內(nèi)
數(shù)據(jù)結(jié)構(gòu)類型為Map類型
ArrayMap<Key,
Value> arrayMap = new ArrayMap<>();

1【注】:如果我們要兼容aip19以下版本的話,那么導(dǎo)入的包需要為v4包
總結(jié)
SparseArray和ArrayMap都差不多,使用哪個呢?
假設(shè)數(shù)據(jù)量都在千級以內(nèi)的情況下:
1、如果key的類型已經(jīng)確定為int類型,那么使用SparseArray,因?yàn)樗苊饬俗詣友b箱的過程,如果key為long類型,它還提供了一個LongSparseArray來確保key為long類型時的使用
2、如果key類型為其它的類型,則使用ArrayMap

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容