在寫SparseArray某些情況下比HashMap性能更好,按照官方問答的解釋,主要是因為SparseArray不需要對key和value進行auto-boxing(將原始類型封裝為對象類型,比如把int類型封裝成Integer類型),結構比HashMap簡單(SparseArray內部主要使用兩個一維數組來保存數據,一個用來存key,一個用來存value)不需要額外的額外的數據結構
key為int的時候才能使用,注意是int而不是Integer,這也是sparseArray效率提升的一個點,去掉了裝箱的操作
插入
100000條數據的存儲使用DDMS查看,hashMap的存儲空間14M左右,而SparseArray自由8M多幾乎是少了40%接近
插入時候,SparseArray 正序插入效率比起倒序插入快了幾乎是10倍, hashMap差不多。
我們是按照1,3,2的順序排列的,但是在SparseArray內部還是按照正序排列的,這時因為SparseArray在檢索數據的時候使用的是二分查找,所以每次插入新數據的時候SparseArray都需要重新排序,所以代碼4中,逆序是最差情況。
SparseArray原理
單純從字面上來理解,SparseArray指的是稀疏數組(Sparse array),所謂稀疏數組就是數組中大部分的內容值都未被使用(或都為零),在數組中僅有少部分的空間使用。因此造成內存空間的浪費,為了節(jié)省內存空間,并且不影響數組中原有的內容值,我們可以采用一種壓縮的方式來表示稀疏數組的內容。
假設有一個97的數組,其內容如下
在此數組中,共有63個空間,但卻只使用了5個元素,造成58個元素空間的浪費。以下我們就使用
其中在稀疏數組中第一部分所記錄的是原數組的列數和行數以及元素使用的個數、第二部分所記錄的是原數組中元素的位置和內容。經過壓縮之后,原來需要聲明大小為63的數組,而使用壓縮后,只需要聲明大小為63的數組,僅需18個存儲空間
繼續(xù)閱讀SparseArray的源碼,從構造方法我們可以看出,它和一般的List一樣,可以預先設置容器大小,默認的大小是10:
public SparseArray() {
this(10);
}
注意事項
SparseArray是android里為<Interger,Object>這樣的Hashmap而專門寫的類,目的是提高內存效率,其核心是折半查找函數(binarySearch)。注意內存二字很重要,因為它僅僅提高內存效率,而不是提高執(zhí)行效率,
它只適用于android系統(tǒng)(內存對android項目有多重要,地球人都知道)。SparseArray有兩個優(yōu)點:1.避免了自動裝箱(auto-boxing),2.數據結構不會依賴于外部對象映射。我們知道HashMap 采用一種所謂的“Hash 算法”來決定每個元素的存儲位置,存放的都是數組元素的引用,通過每個對象的hash值來映射對象。而SparseArray則是用數組數據結構來保存映射,然后通過折半查找來找到對象。但其實一般來說,SparseArray執(zhí)行效率比HashMap要慢一點,因為查找需要折半查找,而添加刪除則需要在數組中執(zhí)行,而HashMap都是通過外部映射。但相對來說影響不大,最主要是SparseArray不需要開辟內存空間來額外存儲外部映射,從而節(jié)省內存