前言
我们知道android为了减小空间的占用,在系统中提供了特有的容器,这里主要是替换了键值对的存取容器,如果能明确知道在使用的过程中键是整型,则替代该类型的Map容器的就是sparse家族了,这里主要有以下几种sparse容器,SparseBooleanArray,SparseIntArray,SparseLongArray,SparseArray.
SparseBooleanArray主要是替换的是值为Boolean类型,SparseIntArray主要替换的是值为Int类型,SparseLongArray主要替换的是值为Long类型,SparseArray是终极大招,存储的是一个泛型E,因此他不仅可以用来替换上面出现的容器,还能存储值为其它类型的值。
这里我们主要来解剖一下SparseBooleanArray,其它的类型大同小异,主要解剖其中不同的地方。
初始化
SparseBooleanArray主要有两个构造函数:构造函数如下
/**
* Creates a new SparseBooleanArray containing no mappings.
*/
public SparseArray() {
this(10);
}
/**
* Creates a new SparseBooleanArray containing no mappings that will not
* require any additional memory allocation to store the specified
* number of mappings. If you supply an initial capacity of 0, the
* sparse array will be initialized with a light-weight representation
* not requiring any additional array allocations.
*/
public SparseArray(int initialCapacity) {
if (initialCapacity == 0) {
mKeys = EmptyArray.INT;
mValues = EmptyArray.BOOLEAN;
} else {
mKeys = ArrayUtils.newUnpaddedIntArray(initialCapacity);
mValues = new boolean[mKeys.length];
}
mSize = 0;
}
无参构造函数最终调用了有参构造函数,并且指定了初始容量为10(这个主要是看的23的源码,不确定其他版本也是该值),在有参构造函数中根据容量进行不同的初始化。当initialCapacity为0时,mKeys初始化为一个INT类型的空数组,mValues初始化为一个BOOLEAN类型的空数组,当initialCapacity为其它值时mKeys由以下代码进行初始化
public static int[] newUnpaddedIntArray(int minLen) {
return (int[])VMRuntime.getRuntime().newUnpaddedArray(int.class, minLen);
}
主要用当前的运行新环境分配一个int类型的,指定长度的数组,mValues分配一个boolean类型的数组。mSize当前已经存储的内容的数量。
存储值
/**
* 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, boolean value) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (i >= 0) {
mValues[i] = value;
} else {
i = ~i;
mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
在存储的时候,先根据指定的key从已有的mKeys数组中二分查找对应的key是否已经存在,如果存在则i返回的是对应key存储的下标,否则返回的对应key应该存储位置的i取反值,当i大于0时即存在时,则覆盖对应下标mValues的值,否则,再将值取反,将key于values分别存储在i所对应的下标中。
二分查找如下:
// This is Arrays.binarySearch(), but doesn't do any argument validation.
static int binarySearch(int[] array, int size, int value) {
int lo = 0;