眾所周知席函,基礎(chǔ)數(shù)組的處理效率要比集合的處理效率高出指數(shù)倍(內(nèi)存尋址優(yōu)勢(shì)铐望,指哪打哪,直截了當(dāng))
在HashMap<K, V> 中K為Integer類(lèi)型時(shí)茂附,簡(jiǎn)單考慮蝌以,使用K作為數(shù)組下標(biāo)可以使用基礎(chǔ)數(shù)組替代HashMap,但這樣處理的話(huà)會(huì)有一個(gè)問(wèn)題何之,那就是K值較大時(shí)跟畅,直接使用數(shù)組會(huì)導(dǎo)致極大的內(nèi)存空間浪費(fèi)(很多數(shù)組內(nèi)容都由null填充)——由此想到“稀疏數(shù)組”
SparseArray就是針對(duì)這一場(chǎng)景設(shè)計(jì)的
數(shù)組中僅僅保存有內(nèi)容的空間 這樣一來(lái),就既可以利用數(shù)組高效的優(yōu)勢(shì)溶推,又避免了內(nèi)存空間的浪費(fèi)徊件。
取android.util.SparseArray源碼中的put API如下:
/**
* Adds a mapping from the specified key to the specified value,
* replacing the previous mapping from the specified key if there
* was one.
*/
public void put(int key, E value) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (i >= 0) {
mValues[i] = value;
} else {
i = ~i;
if (i < mSize && mValues[i] == DELETED) {
mKeys[i] = key;
mValues[i] = value;
return;
}
if (mGarbage && mSize >= mKeys.length) {
gc();
// Search again because indices may have changed.
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
}
mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
可以看到奸攻,在查找是否包含時(shí)使用了BinarySearch(二分搜索),在插入時(shí)又做了一次容量虱痕、size檢查睹耐,有無(wú)用內(nèi)存時(shí)手動(dòng)gc,此gc為private函數(shù)部翘,只是對(duì)內(nèi)存進(jìn)行了整理硝训,無(wú)效內(nèi)容置為null
查看DELETED定義:
private static final Object DELETED = new Object();
在刪除時(shí),只是將有效索引的內(nèi)容至為DELETED新思,將mGarbage至為true窖梁,在下次有增/改操作時(shí)進(jìn)行統(tǒng)一的容量整理;個(gè)人感覺(jué)這一api邏輯是經(jīng)驗(yàn)設(shè)計(jì)夹囚,為的是避免連續(xù)刪除時(shí)的頻繁容量整理纵刘;
結(jié)論:
使用HashMap<Integer, V>時(shí),用SparseArray替代荸哟,可以極大地提高性能