SparseArrays源码分析

    在android开发中,如果要使用到以Integer为key的map的时候,要优先使用SparseArrays。API文档上指明使用SparseArrays可以更高效的使用内存。通过阅读源码,可以看出在SparseArrays的实现中,避免了自动装箱机制,以及舍弃了entry来保存key和value的匹配,而是分别使用了两个数组来保存key和value。但是有利就有弊,这种实现方式就不得不放弃HashMap在查找上面的效率。因为SparseArrays是通过二份查找来实现搜索的,自然比不上HashMap的查找速率。

    另外,由于key和value都是通过数组来保存的,就带来了另外一个问题。这就是数组在增加和删除的时候是比较低效的,原因大家应该都清楚。所以SparseArrays为了避免这个问题,使用了一种在我看来比较巧妙的机制。实现方法是,在删除的时候,并不是立即执行数组的删除操作,而只是把要删的key对于的value置为DELETED,声明语句为private static final Object DELETED = new Object()。同时该类有一个全局变量boolean mGarbage = false;当执行delete操作或者remove操作时,该变量会置为true。当执行查询或者增加等操作的时候,才会根据mGarbage的值来执行真正的删除操作。这样就避免了频繁的对数组进行删除操作,极大了提高了效率。

     最后需要说明的是,SparseArrays会在数组装满的情况下自动扩充容量,避免了对内存的使用浪费。如下面代码所示:

if (pos >= mKeys.length) {
            int n = ArrayUtils.idealIntArraySize(pos + 1);

            int[] nkeys = new int[n];
            Object[] nvalues = new Object[n];

            // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
            System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
            System.arraycopy(mValues, 0, nvalues, 0, mValues.length);

            mKeys = nkeys;
            mValues = nvalues;
        }

相关推荐