SparseIntArray原理分析

栏目: 编程工具 · 发布时间: 6年前

内容简介:SparseSetArray目前在sdk中还处于hide状态,故在做总结的时候就不分析它了。之前已经分析过

SparseArray 优化了 intObject 键值对的存储, SparseIntArray 优化了 intint 键值对的存储。android中在键值对存储上的优化主要做了一下几种类型的优化:

  • int --> Object (SparseArray)
  • int --> int (SparseIntArray)
  • int --> boolean (SparseBooleanArray)
  • int --> long (SparseLongArray)
  • int --> Set (SparseSetArray)

SparseSetArray目前在sdk中还处于hide状态,故在做总结的时候就不分析它了。

之前已经分析过 SparseArray ,本文就分析下 SparseIntArray 的实现,并在最后总结下这几种键值对在实现上的共同点。

继承结构

SparseIntArray原理分析

以上为 SparseIntArray 的继承体系。 SparseIntArray 只实现了 Cloneable 接口,结构比较简单。其实阅读源码可以发现, SparseArraySparseIntArraySparseBooleanArraySparseLongArray 都只实现了 Cloneable 接口。

存储结构

SparseIntArray原理分析

以上为 SparseIntArray 的存储结构,mKeys存储的是int类型的键,mValues存储的是int类型的value。

查找元素

// 查找键key在mKeys的下标
    public int indexOfKey(int key) {
        return ContainerHelpers.binarySearch(mKeys, mSize, key);
    }
    
    // 查找value在mValues的下标
    public int indexOfValue(int value) {
        for (int i = 0; i < mSize; i++)
            if (mValues[i] == value)
                return i;
        return -1;
    }
复制代码

元素的查找分键查找和值查找,键查找使用二分查找,值查找直接使用循环遍历。

添加元素

public void put(int key, int 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数组的下标,也就是value在mValues数组的下标。如果 ContainerHelpers.binarySearch(mKeys,mSize,key) 在mKeys数组中没有找到key,则返回key待插入位置的下标的取反,如果找到了key,则直接更新mValues对应位置的值即可。 GrowingArrayUtils.insert 函数的实现如下:

public static int[] insert(int[] array, int currentSize, int index, int element) {
        assert currentSize <= array.length;
    
        if (currentSize + 1 <= array.length) {
            System.arraycopy(array, index, array, index + 1, currentSize - index);
            array[index] = element;
            return array;
        }
    
        int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
        System.arraycopy(array, 0, newArray, 0, index);
        newArray[index] = element;
        System.arraycopy(array, index, newArray, index + 1, array.length - index);
        return newArray;
    }
复制代码

函数的逻辑很简单,首先断言了currentSize <= array.length;如果array在不需要扩大容量的情况下可以添加一个元素,则先将待插入位置index开始的元素整体后移一位,然后插入元素,否则先扩容,然后将元素拷贝到新的数组中。

删除元素

public void delete(int key) {
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
        if (i >= 0) {
            removeAt(i);
        }
    }
    
    public void removeAt(int index) {
        System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
        System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
        mSize--;
    }
复制代码

删除元素主要涉及以上两个方法, delete(int key) 根据 key 进行删除, removeAt(int index) 删除指定下标的元素。这两个方法都是 public ,故都可以直接使用。 delete(int key) ,先使用二分查找,找到 keymKeys 的下标,如果找到即 i >= 0 ,则直接删除 mKeysmValues 指定位置的元素。

总结

SparseBooleanArray , SparseLongArray 还没有分析,他们的实现规则是一样的,只是存储的数据类型的 mValues 数组是 booleanlong ,接下来就对 SparseIntArray , SparseBooleanArray , SparseLongArray 进行下总结。

  • 他们的设计目的是优化 intint , boolean , long 映射的存储
  • 使用 int 类型的数组 mKeys 存储映射的键,使用对应类型的数组 mValues 存储值
  • int 类型的键在存储上是有顺序的
  • 在查找值时,先使用二分查找,在 mKeys 中查找值在 mValues 中的下标,然后返回值

以上三种数据类型和 SparseArray 最大的区别在于 SparseArray 在删除元素的时候会将元素设置为 DELETED ,后续会有 gc 的过程。

相对于使用HashMap,这样的设计的优势和缺点:

优势:

  • 避免 int 类型的键自动装箱
  • 相较于 HashMap 使用 Node ,这样的设计使用更小的存储单元即可存储 keyvalue 的映射

缺点:

  • 在进行元素查找时使用二分查找,元素较多(谷歌给出的数字是大于1000)时,查找效率较低
  • 在进行元素的添加和删除时,可能会频繁进行元素的移动,运行效率可能会降低

以上所述就是小编给大家介绍的《SparseIntArray原理分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Google總部大揭密

Google總部大揭密

史蒂芬.李維 / 陳重亨 / 財信 / 2011-11

∣如果有一天,Google的搜尋引擎突然故障 ∣GMAIL信件全數消失 ∣Google Maps、Google Docs、Google行事曆等所有雲端服務全面停擺 ∣我們該怎麼辦?! 歷史上像Google如此成功,且廣受推崇的企業可沒幾家。它改變了網路的使用方式,也成了我們生活不可或缺的一部分。這到底是怎麼辦到的? 《連線》雜誌資深主筆史蒂芬.李維史無前例同時取得LS......一起来看看 《Google總部大揭密》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具