返回
SparseArray,一个高效的 Android 数据结构
Android
2023-11-09 01:46:42
SparseArray 是一种数据结构,专为优化 Android 应用程序中的稀疏数据集合而设计。它比标准的数组或映射更有效率,因为它只存储有值的索引和值,而不存储所有可能的索引。这意味着它可以在内存使用量和检索速度方面带来显著的节省。
SparseArray 的优点
- 内存效率: 只存储非空值的索引和值,而不是所有可能的索引。
- 快速查找: 通过索引直接访问元素,无需遍历整个数组或映射。
- 易于使用: 简单的 API,类似于标准的数组或映射。
SparseArray 的缺点
- 插入顺序丢失: SparseArray 不会保留元素的插入顺序。
- 可能产生碎片: 删除元素可能会导致内存碎片,从而降低性能。
SparseArray 的应用场景
SparseArray 非常适合存储稀疏数据集合,例如:
- 稀疏列表或映射
- 缓存
- 稀疏矩阵
- 稀疏索引
SparseArray 的源码解析
构造方法
public SparseArray() {
this(10);
}
public SparseArray(int initialCapacity) {
if (initialCapacity == 0) {
mKeys = EMPTY_INT_ARRAY;
mValues = EMPTY_OBJECT_ARRAY;
} else {
mKeys = new int[initialCapacity];
mValues = new Object[initialCapacity];
}
mSize = 0;
}
SparseArray 的构造方法允许指定初始容量。如果没有指定容量,则使用默认容量 10。如果初始容量为 0,则创建空数组。否则,创建指定容量的新数组。
常用 API
- put(int key, Object value) :将指定值与指定键关联。
- get(int key) :返回与指定键关联的值。
- remove(int key) :移除与指定键关联的元素。
- size() :返回 SparseArray 中元素的数量。
增
public void put(int key, Object value) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (i < 0) {
i = ~i;
if (mSize >= mKeys.length) {
int[] nkeys = new int[mSize + (mSize < 12 ? 8 : (mSize >> 1))];
Object[] nvalues = new Object[mSize + (mSize < 12 ? 8 : (mSize >> 1))];
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
mKeys = nkeys;
mValues = nvalues;
}
if (mSize == i) {
mKeys[i] = key;
mValues[i] = value;
++mSize;
return;
}
System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
mKeys[i] = key;
mValues[i] = value;
++mSize;
} else {
mValues[i] = value;
}
}
put() 方法使用二分查找找到指定键的位置。如果键不存在,则插入键和值。如果键存在,则更新值。
删
public void remove(int key) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (i >= 0) {
System.arraycopy(mKeys, i + 1, mKeys, i, mSize - (i + 1));
System.arraycopy(mValues, i + 1, mValues, i, mSize - (i + 1));
--mSize;
}
}
remove() 方法使用二分查找找到指定键的位置。如果键存在,则删除该键及其关联的值。
改
public void put(int key, Object value) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (i < 0) {
i = ~i;
... // 省略其他代码
} else {
mValues[i] = value;
}
}
put() 方法还可用于更新现有键的值。如果键存在,则更新值。
查
public Object get(int key) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
return i < 0 ? null : mValues[i];
}
get() 方法使用二分查找找到指定键的位置。如果键存在,则返回关联的值。否则,返回 null。