SparseArray的優缺點及適用的應用場景小結
SparseArray的實現簡介:
使用兩個陣列儲存鍵值對,mKeys:int[]和mValue:Object[]。
成員介紹:
mSize:是指mKeys中實際使用的到的長度。
DELETE:Objcet 用於填充被remove的值。
首先是使用mKeys[0],此時mSize=1。然後插入一個數,小於mKeys[0]的,那麼此時要將mKey[0]向後移一位(需要使用system#arraycopy(...)進行移位),然後將新插入的值放到mKeys[0](如果後面還有其他值的話要統一後移一位)。如果此時mSize>=mKeys.length,那麼陣列需要使用system#arraycopy(...)為陣列擴容了,擴容至原來的兩倍,然後將資料移到新陣列中。
鍵在mKeys的index和值在mValues的index是一致的。所以mKeys移位的同時,mValues也需要移位。
被刪除的值使用一叫DELETE的固定Object物件填充。
為什麼叫做SparseArray
而從上可以看出mSize一般是小於mKeys.length的,因為如果不做刪除操作,index=0到index=mSize-1中都是滿的,沒有空的,所以插入時一般都需要從插入位置起,後面元素向後移一位。這應該就是這個類叫做SparseArray(稀疏陣列)的原因。所以覺得這樣的安排把所有元素都緊密的壓縮到一起,即是index為0至mSize-1的位置,而不是分散的分佈在0至mKeys.length-1的整個陣列。而這樣的考慮正符合JavaScript稀疏陣列的目的,所以叫SparseArray。這都是我的猜測。
JavaScript中是這樣定義稀疏陣列:稀疏陣列就是包含從0開始的不連續索引的陣列。通常,陣列的length屬性值代表陣列中元素的個數。如果陣列是稀疏的,length屬性值大於元素的個數。可以用Array()建構函式或簡單地指定陣列的索引值大於當前陣列長度來建立稀疏陣列。
和HashMap、ArrayMap對比,SparseArray的優缺點:
SparseArray的限制在於鍵必須是int型別,值必須是Object型別。這樣可以避免key自動裝箱產生過多的Object。但是這樣的話,如果key值相同,那麼資料就會被直接覆蓋。
SparseArray不能保證保留它們的插入順序,在迭代的時候應該注意。SparseArray中沒有Iterator,SparseArray只實現了Cloneable介面,而沒有繼承Collection、List或者Map介面。
查詢資料的時候使用的是二分法,明顯比通過hashcode慢,所以資料越大,查詢速度慢的劣勢越明顯,所以SparseArray適於資料一千以內的場景中。
優點:
- 避免了基本資料型別的裝箱操作
- 不需要額外的結構體,單個元素的儲存成本更低
- 資料量小的情況下,隨機訪問的效率更高
缺點:
- 插入操作需要複製陣列,增刪效率降低
- 資料量巨大時,複製陣列成本巨大,
gc()
成本也巨大 - 資料量巨大時,查詢效率也會明顯下降