Java提供了HashMap<key, value>存储key/value的数据类型,而Android提供了优化的实现方式:SparseArray<E>、SparseBooleanArray、SparseIntArray、SparseLongArray,进一步提高了效率。
部分定义代码如下:
public class SparseArray<E> implements Cloneable { // map Integers to Objects
private int[] mKeys;
private Object[] mValues;
private int mSize;
......
public class SparseBooleanArray implements Cloneable { // map Integers to Booleans
private int[] mKeys;
private boolean[] mValues;
private int mSize;
......
public class SparseIntArray implements Cloneable { // map Integers to Integers
private int[] mKeys;
private int[] mValues;
private int mSize;
......
public class SparseLongArray implements Cloneable { // map Integers to Longs
private int[] mKeys;
private long[] mValues;
private int mSize;
......
从代码可以看出,实现方式相似,只是根据values的类型不同,定义了不同的数据类型。另外需要注意的是采用了基本数据类型,避免了数据的自动拆装箱,因此空间效率高。另外这些对象以数组来保存映射关系,并使用二分查找来查找key。这种实现方式并不适合于大量的数据集。由于查找需要二分查找,添加和移除需要插入和删除数组中的元素,因此一般情况下都会比HashMap更慢。如果包含了数百元素,这个性能差别就不是很明显,小于50%。
为了提高性能,对移除操作进行了优化:并不立即压缩数据,而是将移除的元素标记为“deleted”。这个元素之后能被相同的key值所重用,或者在之后的gc环节将移除的所有元素一起压缩。可以在数组增长、映射大小或者元素值被获取的任何时候,gc操作都需要被执行。
遍历的方法:
int key = 0;
for(int i = 0; i < sparseArray.size(); i++) {
key = sparseArray.keyAt(i);
Object obj = sparseArray.get(key);
//或者 Object obj = sparseArray.valueAt(i);
}
另外,在android.support.v4.util下,提供了一些补充类:
public class LongSparseArray<E> implements Cloneable { // map Longs to Objects
private long[] mKeys;
private Object[] mValues;
private int mSize;
参考资料:
1、...sdk/docs/reference/android/util/SparseArray.html
2、http://www.liaohuqiu.net/cn/posts/sparse-array-in-android/