SparseArray与ArrayMap

SparseArray

SparseArray核心代码

两个构造函数默认数组容量10
public SparseArray() {
   this(10);
}
public SparseArray(int initialCapacity) {
    if (initialCapacity == 0) {
        mKeys = EmptyArray.INT;
        mValues = EmptyArray.OBJECT;
    } else {
        mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
        mKeys = new int[mValues.length];
    }
    mSize = 0;
}

//通过 key 来返回对应的 value,前面在分析 put() 的时候已经分析过了二分查找。那么这里如果找到了,就会通过下标直接从 mValues[] 中返回。
public E get(int key, E valueIfKeyNotFound) {
    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
    if (i < 0 || mValues[i] == DELETED) {
        return valueIfKeyNotFound;
    } else {
        return (E) mValues[i];
    }
}

//This is Arrays.binarySearch(), but doesn't do any argument validation.
public static int binarySearch(int[] array, int size, int value) {
    int lo = 0;
    int hi = size - 1;
    while (lo <= hi) {
        // 高位+低位之各除以 2,写成右移,即通过位运算替代除法以提高运算效率
        final int mid = (lo + hi) >>> 1;
        final int midVal = array[mid];
        if (midVal < value) {
            lo = mid + 1;
        } else if (midVal > value) {
            hi = mid - 1;
        } else {
            return mid;  // value found
        }
    }
    //若没找到,则lo是value应该插入的位置,是一个正数。对这个正数去反,返回负数回去
    return ~lo;  // value not present
}

public void put(int key, E value) {
    // 1.先进行二分查找
    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
    // 2. 如果找到了,则 i 必大于等于 0
    if (i >= 0) {
        mValues[i] = value;
    } else {
    // 3. 没找到,则找一个正确的位置再插入
        i = ~i;
        if (i < mSize && mValues[i] == DELETED) {
            mKeys[i] = key;
            mValues[i] = value;
            return;
        }
        //可能value元素已经被删除了
        if (mGarbage && mSize >= mKeys.length) {
            gc();//执行一次压缩,此gc非jvm的gc
            // 重新搜索一遍
            i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
        }
        mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
        mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
        mSize++;
    }
}

public static int[] insert(int[] array, int currentSize, int index, int element) {
    //确认 当前集合长度 小于等于 array数组长度
    assert currentSize <= array.length;
    //不需要扩容
    if (currentSize + 1 <= array.length) {
        //将array数组内从 index 移到 index + 1,共移了 currentSize - index 个,即从index开始后移一位,那么就留出 index 的位置来插入新的值。
        System.arraycopy(array, index, array, index + 1, currentSize - index);
        //在index处插入新的值
        array[index] = element;
        return array;
    }
    //需要扩容,构建新的数组,新的数组大小由growSize() 计算得到
    int[] newArray = new int[growSize(currentSize)];
    //这里再分 3 阶段赋值。
    //1.将原数组中 index 之前的数据复制到新数组中
    System.arraycopy(array
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值