SparseArray原理
單純從字面上來理解,SparseArray指的是稀疏數(shù)組(Sparse array),所謂稀疏數(shù)組就是數(shù)組中大部分的內(nèi)容值都未被使用(或都為零),在數(shù)組中僅有少部分的空間使用。因此造成內(nèi)存空間的浪費(fèi),為了節(jié)省內(nèi)存空間,并且不影響數(shù)組中原有的內(nèi)容值,我們可以采用一種壓縮的方式來表示稀疏數(shù)組的內(nèi)容。
假設(shè)有一個97的數(shù)組,其內(nèi)容如下
在此數(shù)組中,共有63個空間,但卻只使用了5個元素,造成58個元素空間的浪費(fèi)。以下我們就使用稀疏數(shù)組重新來定義這個數(shù)組:
其中在稀疏數(shù)組中第一部分所記錄的是原數(shù)組的列數(shù)和行數(shù)以及元素使用的個數(shù)、第二部分所記錄的是原數(shù)組中元素的位置和內(nèi)容。經(jīng)過壓縮之后,原來需要聲明大小為63的數(shù)組,而使用壓縮后,只需要聲明大小為6*3的數(shù)組,僅需18個存儲空間
繼續(xù)閱讀SparseArray的源碼,從構(gòu)造方法我們可以看出,它和一般的List一樣,可以預(yù)先設(shè)置容器大小,默認(rèn)的大小是10:
public SparseArray() {
this(10);
}
注意事項(xiàng)
SparseArray是android里為<Interger,Object>這樣的Hashmap而專門寫的類,目的是提高內(nèi)存效率,其核心是折半查找函數(shù)(binarySearch)。注意內(nèi)存二字很重要,因?yàn)樗鼉H僅提高內(nèi)存效率,而不是提高執(zhí)行效率,
它只適用于android系統(tǒng)(內(nèi)存對android項(xiàng)目有多重要,地球人都知道)。SparseArray有兩個優(yōu)點(diǎn):1.避免了自動裝箱(auto-boxing),2.數(shù)據(jù)結(jié)構(gòu)不會依賴于外部對象映射。我們知道HashMap 采用一種所謂的“Hash 算法”來決定每個元素的存儲位置,存放的都是數(shù)組元素的引用,通過每個對象的hash值來映射對象。而SparseArray則是用數(shù)組數(shù)據(jù)結(jié)構(gòu)來保存映射,然后通過折半查找來找到對象。但其實(shí)一般來說,SparseArray執(zhí)行效率比HashMap要慢一點(diǎn),因?yàn)椴檎倚枰郯氩檎遥砑觿h除則需要在數(shù)組中執(zhí)行,而HashMap都是通過外部映射。但相對來說影響不大,最主要是SparseArray不需要開辟內(nèi)存空間來額外存儲外部映射,從而節(jié)省內(nèi)存
SparseArray 的使用
@SuppressWarnings("unchecked")
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);
}
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
if (convertView == null) {
convertView = LayoutInflater.from(context)
.inflate(R.layout.banana_phone, parent, false);
}