Android---SparseArray

SparseArray

在Android API里,Google提供了一种替代HashMap<Integer, E>的数据结构,这种数据结构就是SparseArray。

先来回顾下HashMap,HashMap是由 数组 + 单向链表 组成的容器,默认大小为16,每次put时算出index,然后放入数组内,这样造成的问题就是内存中数组元素不是连续的,而是散列的,因此浪费了内存。

而SparseArray就是为了解决这个问题而产生的。


 

先来看看SparseArray的成员变量

public class SparseArray<E> implements Cloneable {
    private static final Object DELETED = new Object();
    private boolean mGarbage = false;

    private int[] mKeys;       //存放所有的key
    private Object[] mValues;  //存放所有的value
    private int mSize;         //容器容量

在SparseArray里,有两个数组,一个数组存放key,一个存放value。


再看一下SparseArray的构造函数

    public SparseArray() {
        this(10);    //空参构造函数,默认容量为10
    }
    public SparseArray(int initialCapacity) {
        if (initialCapacity == 0) {
            mKeys = EmptyArray.INT;
            mValues = EmptyArray.OBJECT;
        } else {
            //生成固定大小的数组,存放value
            mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
            mKeys = new int[mValues.length];    //根据value,生成对应容量的key数组
        }
        mSize = 0;
    }

 


我们看一下put方法

    public void put(int key, E value) {
        //通过二分查找,找到对应的index
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

        if (i >= 0) {
            //如果有此元素,在对应位置覆盖value
            mValues[i] = value;
        } else {
            //如果没有此元素, 取反操作
            i = ~i;

            if (i < mSize && mValues[i] == DELETED) {
                //取反后,如果这个位置的元素被删除了,那么重新存入当前元素
                mKeys[i] = key;
                mValues[i] = value;
                return;
            }

            if (mGarbage && mSize >= mKeys.length) {
                //如果容量已经比真实元素大,GC。
                gc();

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

            //插入元素
            mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
            mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
            mSize++;
        }
    }

看一下get方法

    public E get(int key, E valueIfKeyNotFound) {
        //二分查找index
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

        //如果没有此key或者已经删除,就返回传入的valueIfKeyNotFound
        if (i < 0 || mValues[i] == DELETED) {
            return valueIfKeyNotFound;
        } else {
            //返回找到的元素
            return (E) mValues[i];
        }
    }

看一下delete方法

    public void delete(int key) {
        //二分查找找到index
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

        if (i >= 0) {
            if (mValues[i] != DELETED) {
                //标记删除元素,等待GC
                mValues[i] = DELETED;
                mGarbage = true;
            }
        }
    }


 总结:

SparseArray是两个数组组成的键值对容器,key的数据类型只能为int,每次都通过二分查找来寻找key。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值