作用
用來(lái)替代key為int的HashMap
分析
源碼中的相關(guān)分析:
package android.util;
import com.android.internal.util.ArrayUtils;
/**
* SparseArrays 利用integer去管理object對(duì)象。不像一個(gè)正常的object對(duì)象數(shù)組,它能在索引數(shù)中快速的查找到所需的結(jié)果粒没。(這
* 句話是音譯,原意是能在眾多索引數(shù)中“撕開一個(gè)缺口”,為什么原文這么表達(dá)?下面會(huì)慢慢說(shuō)清楚倾贰。)它比HashMap去通過(guò)Integer索引
* 查找object對(duì)象時(shí)在內(nèi)存上更具效率,不僅因?yàn)樗苊饬擞脕?lái)查找的自動(dòng)“裝箱”的keys,并且它的數(shù)據(jù)結(jié)構(gòu)不依賴額外的對(duì)象去
* 各個(gè)映射中查找匹配滚粟。
*
* SparseArrays map integers to Objects. Unlike a normal array of Objects,
* there can be gaps in the indices. It is intended to be more memory efficient
* than using a HashMap to map Integers to Objects, both because it avoids
* auto-boxing keys and its data structure doesn't rely on an extra entry object
* for each mapping.
*
* 請(qǐng)注意寻仗,這個(gè)容器會(huì)保持它的映射關(guān)系在一個(gè)數(shù)組的數(shù)據(jù)結(jié)構(gòu)中刃泌,通過(guò)二分檢索法驅(qū)查找key。(這里我們終于知道署尤,為何這個(gè)工具類中耙替,
* 提供的添加映射關(guān)系的操作中,key的類型必須是integer曹体。因?yàn)槎謾z索法俗扇,將從中間“切開”,integer的數(shù)據(jù)類型是實(shí)現(xiàn)這種檢索過(guò)程的保證箕别。)
*
* 如果保存大量的數(shù)據(jù)铜幽,這種數(shù)據(jù)結(jié)構(gòu)是不適合的,換言之串稀,SparseArray這個(gè)工具類并不應(yīng)該用于存儲(chǔ)大量的數(shù)據(jù)除抛。這種情況下,它的效率
* 通常比傳統(tǒng)的HashMap更低母截,因?yàn)樗牟檎曳椒ú⑶以黾雍鸵瞥僮鳎ㄈ我庖粋€(gè)操作)都需要在數(shù)組中插入和刪除(兩個(gè)步驟才能實(shí)現(xiàn))到忽。
*
* 如果存儲(chǔ)的數(shù)據(jù)在幾百個(gè)以內(nèi),它們的性能差異并不明顯清寇,低于50%喘漏。
*
* (OK,那么光看Android官方的介紹我們就有初步結(jié)論了华烟,大量的數(shù)據(jù)我們相對(duì)SparseArray會(huì)優(yōu)先選擇HashMap翩迈,如果數(shù)據(jù)在幾百個(gè)這個(gè)數(shù)目,
* 那么選擇它們?nèi)我庖粋€(gè)去實(shí)現(xiàn)區(qū)別不大盔夜,如果數(shù)量較少负饲,就選擇SparseArray去實(shí)現(xiàn)。 其實(shí)如果我們理解了二分法比吭,就很容易了SparseArray的
* 實(shí)現(xiàn)原理绽族,以及SparseArray和HashMap它們之間的區(qū)別了。)
*
* <p>Note that this container keeps its mappings in an array data structure,
* using a binary search to find keys. The implementation is not intended to be appropriate for
* data structures
* that may contain large numbers of items. It is generally slower than a traditional
* HashMap, since lookups require a binary search and adds and removes require inserting
* and deleting entries in the array. For containers holding up to hundreds of items,
* the performance difference is not significant, less than 50%.</p>
*
*
* 為了提高性能衩藤,這個(gè)容器包含了一個(gè)實(shí)現(xiàn)最優(yōu)的方法:當(dāng)移除keys后為了立刻使它的數(shù)組緊密吧慢,它會(huì)“遺留”已經(jīng)被移除(標(biāo)記了要?jiǎng)h除)的條目(entry) 。
* 所被標(biāo)記的條目(entry)(還未被當(dāng)作垃圾回收掉前)可以被相同的key復(fù)用赏表,也會(huì)在垃圾回收機(jī)制當(dāng)作所有要回收的條目的一員被回收检诗,從而使存儲(chǔ)的數(shù)組更緊密匈仗。
*
* (我們下面看源碼就會(huì)發(fā)現(xiàn)remove()方法其實(shí)是調(diào)用delete()方法的。印證了上面這句話所說(shuō)的這種優(yōu)化方法逢慌。
* 因?yàn)檫@樣悠轩,能在每次移除元素后一直保持?jǐn)?shù)組的數(shù)據(jù)結(jié)構(gòu)是緊密不松散的。)
*
* 垃圾回收的機(jī)制會(huì)在這些情況執(zhí)行:數(shù)組需要擴(kuò)充攻泼,或者映射表的大小被恢復(fù)火架,或者條目值被重新檢索后恢復(fù)的時(shí)候。
*
* <p>To help with performance, the container includes an optimization when removing
* keys: instead of compacting its array immediately, it leaves the removed entry marked
* as deleted. The entry can then be re-used for the same key, or compacted later in
* a single garbage collection step of all removed entries. This garbage collection will
* need to be performed at any time the array needs to be grown or the the map size or
* entry values are retrieved.</p>
*
* 當(dāng)調(diào)用keyAt(int)去獲取某個(gè)位置的key的鍵的值忙菠,或者調(diào)用valueAt(int)去獲取某個(gè)位置的值時(shí)何鸡,可能是通過(guò)迭代容器中的元素
* 去實(shí)現(xiàn)的。
*
* <p>It is possible to iterate over the items in this container using
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
* order in the case of <code>valueAt(int)<code>.</p>
*/
public class SparseArray<E> implements Cloneable {
//...
}
package android.util;
import com.android.internal.util.ArrayUtils;
/**
* SparseArrays 利用integer去管理object對(duì)象牛欢。不像一個(gè)正常的object對(duì)象數(shù)組骡男,它能在索引數(shù)中快速的查找到所需的結(jié)果。(這
* 句話是音譯傍睹,原意是能在眾多索引數(shù)中“撕開一個(gè)缺口”隔盛,為什么原文這么表達(dá)?下面會(huì)慢慢說(shuō)清楚拾稳。)它比HashMap去通過(guò)Integer索引
* 查找object對(duì)象時(shí)在內(nèi)存上更具效率,不僅因?yàn)樗苊饬擞脕?lái)查找的自動(dòng)“裝箱”的keys吮炕,并且它的數(shù)據(jù)結(jié)構(gòu)不依賴額外的對(duì)象去
* 各個(gè)映射中查找匹配。
*
* SparseArrays map integers to Objects. Unlike a normal array of Objects,
* there can be gaps in the indices. It is intended to be more memory efficient
* than using a HashMap to map Integers to Objects, both because it avoids
* auto-boxing keys and its data structure doesn't rely on an extra entry object
* for each mapping.
*
* 請(qǐng)注意熊赖,這個(gè)容器會(huì)保持它的映射關(guān)系在一個(gè)數(shù)組的數(shù)據(jù)結(jié)構(gòu)中来屠,通過(guò)二分檢索法驅(qū)查找key。(這里我們終于知道震鹉,為何這個(gè)工具類中俱笛,
* 提供的添加映射關(guān)系的操作中,key的類型必須是integer传趾。因?yàn)槎謾z索法迎膜,將從中間“切開”,integer的數(shù)據(jù)類型是實(shí)現(xiàn)這種檢索過(guò)程的保證浆兰。)
*
* 如果保存大量的數(shù)據(jù)磕仅,這種數(shù)據(jù)結(jié)構(gòu)是不適合的,換言之簸呈,SparseArray這個(gè)工具類并不應(yīng)該用于存儲(chǔ)大量的數(shù)據(jù)榕订。這種情況下,它的效率
* 通常比傳統(tǒng)的HashMap更低蜕便,因?yàn)樗牟檎曳椒ú⑶以黾雍鸵瞥僮鳎ㄈ我庖粋€(gè)操作)都需要在數(shù)組中插入和刪除(兩個(gè)步驟才能實(shí)現(xiàn))劫恒。
*
* 如果存儲(chǔ)的數(shù)據(jù)在幾百個(gè)以內(nèi),它們的性能差異并不明顯,低于50%两嘴。
*
* (OK丛楚,那么光看Android官方的介紹我們就有初步結(jié)論了,大量的數(shù)據(jù)我們相對(duì)SparseArray會(huì)優(yōu)先選擇HashMap憔辫,如果數(shù)據(jù)在幾百個(gè)這個(gè)數(shù)目趣些,
* 那么選擇它們?nèi)我庖粋€(gè)去實(shí)現(xiàn)區(qū)別不大,如果數(shù)量較少贰您,就選擇SparseArray去實(shí)現(xiàn)坏平。 其實(shí)如果我們理解了二分法,就很容易了SparseArray的
* 實(shí)現(xiàn)原理枉圃,以及SparseArray和HashMap它們之間的區(qū)別了功茴。)
*
* <p>Note that this container keeps its mappings in an array data structure,
* using a binary search to find keys. The implementation is not intended to be appropriate for
* data structures
* that may contain large numbers of items. It is generally slower than a traditional
* HashMap, since lookups require a binary search and adds and removes require inserting
* and deleting entries in the array. For containers holding up to hundreds of items,
* the performance difference is not significant, less than 50%.</p>
*
*
* 為了提高性能庐冯,這個(gè)容器包含了一個(gè)實(shí)現(xiàn)最優(yōu)的方法:當(dāng)移除keys后為了立刻使它的數(shù)組緊密孽亲,它會(huì)“遺留”已經(jīng)被移除(標(biāo)記了要?jiǎng)h除)的條目(entry) 。
* 所被標(biāo)記的條目(entry)(還未被當(dāng)作垃圾回收掉前)可以被相同的key復(fù)用展父,也會(huì)在垃圾回收機(jī)制當(dāng)作所有要回收的條目的一員被回收返劲,從而使存儲(chǔ)的數(shù)組更緊密。
*
* (我們下面看源碼就會(huì)發(fā)現(xiàn)remove()方法其實(shí)是調(diào)用delete()方法的栖茉。印證了上面這句話所說(shuō)的這種優(yōu)化方法篮绿。
* 因?yàn)檫@樣,能在每次移除元素后一直保持?jǐn)?shù)組的數(shù)據(jù)結(jié)構(gòu)是緊密不松散的吕漂。)
*
* 垃圾回收的機(jī)制會(huì)在這些情況執(zhí)行:數(shù)組需要擴(kuò)充亲配,或者映射表的大小被恢復(fù),或者條目值被重新檢索后恢復(fù)的時(shí)候惶凝。
*
* <p>To help with performance, the container includes an optimization when removing
* keys: instead of compacting its array immediately, it leaves the removed entry marked
* as deleted. The entry can then be re-used for the same key, or compacted later in
* a single garbage collection step of all removed entries. This garbage collection will
* need to be performed at any time the array needs to be grown or the the map size or
* entry values are retrieved.</p>
*
* 當(dāng)調(diào)用keyAt(int)去獲取某個(gè)位置的key的鍵的值吼虎,或者調(diào)用valueAt(int)去獲取某個(gè)位置的值時(shí),可能是通過(guò)迭代容器中的元素
* 去實(shí)現(xiàn)的苍鲜。
*
* <p>It is possible to iterate over the items in this container using
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
* <code>keyAt(int)</code> with ascending values of the index will return the
* keys in ascending order, or the values corresponding to the keys in ascending
* order in the case of <code>valueAt(int)<code>.</p>
*/
public class SparseArray<E> implements Cloneable {
//...
}
對(duì)比HashMap
- 優(yōu)勢(shì)
空間上 去除了hash值的存儲(chǔ)空間
時(shí)間上 少了自動(dòng)裝箱的過(guò)程 效率提高 - 劣勢(shì)
不適合數(shù)據(jù)量很大的數(shù)據(jù) 因?yàn)椴捎玫亩植檎?strong>(O(logn)) 大數(shù)據(jù)下明顯效率低于hash查找(O(1))