SparseIntArray原理分析

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

内容简介: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原理分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Web 2.0 Architectures

Web 2.0 Architectures

Duane Nickull、Dion Hinchcliffe、James Governor / O'Reilly / 2009 / USD 34.99

The "Web 2.0" phenomena has become more pervasive than ever before. It is impacting the very fabric of our society and presents opportunities for those with knowledge. The individuals who understand t......一起来看看 《Web 2.0 Architectures》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具