SparseArray 稀疏数组源码分析

SparseArray sparse 稀疏

介绍

SparseArray 用来实现 int 类型与 Object 类型的映射,跟普通的 Map 不同,普通 Map 中有更多的空索引,对比 HashMap 来说,稀疏数组实现了更高效的内存使用,因为稀疏数组避免了 int 类型 key 的自动装箱,且稀疏数组每个 value 都不需要使用 Entry 对象来包装。所以在 Android 开发中,我们可以使用 SparseArray 来实现更高效的实现 Map

SparseArray 实现了 Cloneable 接口,说明时支持克隆操作的,下面慢慢分析增删改查以及克隆等操作

一、成员变量

/**
 * 删除操作时替换对应位置 value 的默认值
 */
private static final Object DELETED = new Object();
/**
 * 是否需要回收
 */
private boolean mGarbage = false;
/**
 * 存储 key 的数组
 */
private int[] mKeys;
/**
 * 存储 value 的数组
 */
private Object[] mValues;
/**
 * 当前存储的键值对数量
 */
private int mSize;

SparseArray 中声明了一个 int 类型的数组和一个 Object 类型的数组

二、构造函数

/**
 * 创建一个空 map 初始容量为 10
 */
public SparseArray() { this(10); }

/**
 * 根据指定初始容量创建键值对为空的稀疏数组,并且不会申请额外内存;指定初始容量为 0 时会创建一个轻量级的不需要任何内存分配的稀疏数组
 * capacity 容量
 */
public SparseArray(int initialCapacity) {
    if (initialCapacity == 0) {
        mKeys = EmptyArray.INT; // 长度为 0 的 int 类型数组
        mValues = EmptyArray.OBJECT; // 长度为 0 的 Object 类型数组
    } else {
        mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
        mKeys = new int[mValues.length];
    }
    mSize = 0;
}

SparseArray 有两个构造函数,默认时创建初始容量为 10 数组,另外一个时可以使用者指定出事容量的数量

三、添加/修改 操作

public void put(int key, E value) {
    int i = ContainerHelpers.binarySearch(mKeys, mSize, key); // 使用二分法查找对应的 key 在数组中的下标

    if (i >= 0) { // 索引大于等于 0 说明原数组中有对应 key
        mValues[i] = value; // 则直接 Value 数组中的 value 值为最新的 value
    } else { // 索引小于 0 说明原数组中不存在对应的 key
        i = ~i; // 取反后得到当前 key 应该在的位置

        if (i < mSize && mValues[i] == DELETED) { // 如果数组长度够,并且当前位置已被回收则直接对该位置赋值
            mKeys[i] = key;
            mValues[i] = value;
            return;
        }

        if (mGarbage && mSize >= mKeys.length) { // 回收状态为 true 并且内容长度大于等于 key 数组长度
            gc(); // 回收,整理数组

            // Search again because indices may have changed.
            i = ~ContainerHelpers.binarySearch(mKeys, mSize, key); // 再次使用二分法查找位置
        }

        mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key); // 执行 key 插入到 k
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值