美文网首页
SparseArray源码分析

SparseArray源码分析

作者: wislie_zhu | 来源:发表于2020-02-25 23:20 被阅读0次

类似于Map中存放键值对, 只不过key存放在使用int数组中,而value存放在Object数组中;
核心思想: 采用二分法查询key对应的位置,然后取出值或者插入值

put方法
1.采用二分法查找,获取key在mKeys数组的下标 i
2.如果i >= 0, 说明key在mKeys数组已存在, mValues[i] = value
3.如果i < 0, 说明key在mKeys数组中不存在, i = ~i 按位取反, i 为要添加的元素在数组中的下标
3.1 mValues[i] == DELETED, 表示下标 i 位置的元素有移除过, 如果新添加的元素也是下标 i,mKey[i]和mValues[i] 重新赋值
3.2 mValues[i] != DELETED, 如果mKeys数组中还有元素未赋值, 可能会偏移mKeys数组和mValues数组中的元素; 如果mKeys数组中的元素都赋值过了,对mKeys数组和mValues数组进行扩容,并偏移mKeys数组和mValues数组中的元素.最后都会将key和value分别赋值给mKey[i]和mValues[i];

    public void put(int key, E value) {

        /**
         * 采用二分法查找key,返回的是key在在mKeys数组的下标
         */
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

        //1.mKeys中包含key,value替换
        if (i >= 0) {
            mValues[i] = value;
        } else {
            i = ~i;

            //添加之前,数组下标i位置的元素被删除过
            if (i < mSize && mValues[i] == DELETED) {
                mKeys[i] = key;
                mValues[i] = value;
                return;
            }

            if (mGarbage && mSize >= mKeys.length) {
                gc();

                // Search again because indices may have changed.
                i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
            }

            //添加元素 2.mKeys中不包含key,并且mKeys中元素没有添加满,添加元素;3.mKeys中不包含key,并且mKeys中元素添加满了,扩容,并添加元素
            mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
            mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
            mSize++;
        }
    }

get方法
采用二分法查找,获取key在mKeys数组的下标 i,并返回 i

通过反射,查看添加元素后的变化情况

SparseArray<String> sparseArray = new SparseArray<>(3);
sparseArray.put(5, "wislie");
sparseArray.put(1, "kotlin");
sparseArray.put(1, "java");
sparseArray.put(9, "python");
sparseArray.put(6, "react");
sparseArray.put(4, "flutter");
//打印结果
keys:[5, 0, 0] values:[wislie, null, null] size:1 isGarbage:false
keys:[1, 5, 0] values:[kotlin, wislie, null] size:2 isGarbage:false
keys:[1, 5, 0] values:[java, wislie, null] size:2 isGarbage:false
keys:[1, 5, 9] values:[java, wislie, python] size:3 isGarbage:false
keys:[1, 5, 6, 9, 0, 0, 0, 0, 0] values:[java, wislie, react, python, null, null, null, null, null] size:4 isGarbage:false
keys:[1, 4, 5, 6, 9, 0, 0, 0, 0] values:[java, flutter, wislie, react, python, null, null, null, null] size:5 isGarbage:false 

优点
1.使用二分法, key以升序的方式排列, 提升了内存的利用率及访问效率
2.使用int数组存储int类型的key,避免了int到Integer的自动装箱机制

使用场景
元素个数少于1000, 增删不频繁, key是整型

相关文章

  • SparseArray源码分析

    SparseArray源码分析 SparseArray(稀疏数组)是什么?类似于map,可以储存key-value...

  • SparseArray源码分析

    SparseArray是Android官方推荐的一种高效率的Map类工具,如果key值是int值,最好使用Spar...

  • SparseArray源码分析

    SparseArray是android.util包中提供的类,用于建立整数对对象的映射,比HashMap性能更佳,...

  • SparseArray源码分析

    SparseArray使用 创建 SparseArray有两个构造方法,一个空构造方法,一个可以传入具体容量。Sp...

  • SparseArray源码分析

    类似于Map中存放键值对, 只不过key存放在使用int数组中,而value存放在Object数组中;核心思想: ...

  • SparseArray源码分析

    引子 SparseArray是google官方提供的一种int到Object的map,文档见:SparseArra...

  • ArrayMap源码解析

    上篇文章是SparseArray源码解析,这篇文章分析下ArrayMap的源码。 在移动设备端内存资源很珍贵,Ha...

  • SparseArray的源码分析

    今天给大家带来的是 SparseArray的源码分析:通常的,我们在java中有了一个叫做hashmap的集合,那...

  • 容器类源码解析系列(四)---SparseArray分析(最新版

    容器类源码解析系列(四)---SparseArray分析(最新版) 引言 容器类源码解析系列已经更新到了第四篇,前...

  • SparseArray解析

    注:SparseArray来自于Android源码问题:1、什么是SparseArray?2、SparseArra...

网友评论

      本文标题:SparseArray源码分析

      本文链接:https://www.haomeiwen.com/subject/sqphchtx.html