Android---ArrayMap

ArrayMap

ArrayMap是Android中提供的另外一种容器,用来替代HashMap。

上一篇文章已经讲过了,HashMap的内存浪费,而SparseArray,利用两个数组分别记录Key和Value。通过二分查找来查找Value。

但SparseArray的Key只能是int类型,而ArrayMap,则解决了这个问题,Key支持任何数据类型。 


ArrayMap的重要成员变量 


    int[] mHashes;      //用来存放计算Key的Hash值
    Object[] mArray;    //用来存放Value
    int mSize;          //容量
    

从成员变量上看,大概可以知道ArrayMap并不保存Key值,而是计算出int类型的key值的hash值,记录下来。

但其实ArrayMap的value数组不是想象的这个样子。

mHashes存放key值的hash值。

而mArray其实是存放key + value的。如下图

Android---ArrayMap_第1张图片


构造函数

    public ArrayMap(int capacity, boolean identityHashCode) {
        mIdentityHashCode = identityHashCode;     //是否系统计算hash
        if (capacity < 0) {   //赋值空数组
            mHashes = EMPTY_IMMUTABLE_INTS;
            mArray = EmptyArray.OBJECT;
        } else if (capacity == 0) {  //赋值默认数组
            mHashes = EmptyArray.INT;
            mArray = EmptyArray.OBJECT;
        } else {
            allocArrays(capacity);    //申请数组
        }
        mSize = 0;
    }

 


    @Override
    public V put(K key, V value) {
        final int osize = mSize;
        final int hash;
        int index;
        if (key == null) {  //key为null,hash为0
            hash = 0;
            index = indexOfNull();
        } else {
            hash = mIdentityHashCode ? System.identityHashCode(key) : key.hashCode();
            index = indexOf(key, hash);
        }
        if (index >= 0) {
            index = (index<<1) + 1;
            final V old = (V)mArray[index];
            mArray[index] = value;
            return old;
        }

        index = ~index;
        if (osize >= mHashes.length) {
            final int n = osize >= (BASE_SIZE*2) ? (osize+(osize>>1))
                    : (osize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE);

            if (DEBUG) Log.d(TAG, "put: grow from " + mHashes.length + " to " + n);

            final int[] ohashes = mHashes;
            final Object[] oarray = mArray;
            allocArrays(n);

            if (CONCURRENT_MODIFICATION_EXCEPTIONS && osize != mSize) {
                throw new ConcurrentModificationException();
            }

            if (mHashes.length > 0) {
                if (DEBUG) Log.d(TAG, "put: copy 0-" + osize + " to 0");
                System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length);
                System.arraycopy(oarray, 0, mArray, 0, oarray.length);
            }

            freeArrays(ohashes, oarray, osize);
        }

        if (index < osize) {
            if (DEBUG) Log.d(TAG, "put: move " + index + "-" + (osize-index)
                    + " to " + (index+1));
            System.arraycopy(mHashes, index, mHashes, index + 1, osize - index);
            System.arraycopy(mArray, index << 1, mArray, (index + 1) << 1, (mSize - index) << 1);
        }

        if (CONCURRENT_MODIFICATION_EXCEPTIONS) {
            if (osize != mSize || index >= mHashes.length) {
                throw new ConcurrentModificationException();
            }
        }
        mHashes[index] = hash;
        mArray[index<<1] = key;
        mArray[(index<<1)+1] = value;
        mSize++;
        return null;
    }

 


 待续。

 

你可能感兴趣的:(Android,ArrayMap)