合理使用ArrayMap代替HashMap

轉載請標註:
披薩大叔的博客 http://blog.csdn.net/qq_27258799/article/details/51861350

我們都知道當key是int的時候,用SparseArray代替HashMap是個更省內存的方案。如果key是String或者其他自定義類型呢,不要忘了還有ArrayMap。
ArrayMap是一個< key,value >映射的數據結構,它設計上更多的是考慮內存的優化,內部是使用兩個數組進行數據存儲,一個數組記錄key的hash值,另外一個數組記錄Value值,它和SparseArray一樣,也會對key使用二分法進行從小到大排序,在添加、刪除、查找數據的時候都是先使用二分查找法得到相應的index,然後通過index來進行添加、查找、刪除等操作,所以,應用場景和SparseArray的一樣,如果在數據量比較大的情況下,那麼它的性能將退化至少50%。
所以ArrayMap是犧牲了時間換區空間。在寫手機app時,適時的使用ArrayMap,會給內存使用帶來可觀的提升。
ArrayMap和HashMap主要不同之處在於:
1、存儲方式不同:ArrayMap內部使用兩個數組,一個存HashCode,一個存鍵值對對象。HashMap內部是Entry對象,沒看過HashMap源碼的,可以先看看 HashMap源碼分析
2、擴容方式不同:上面HashMap源碼分析這篇文章說過了,HashMap初始大小是16,達到滿容量的0.75時,要擴容,每次都是上次容量的2倍。而ArrayMap是這樣
//如果容量不夠
if (mSize >= mHashes.length) {
final int n = mSize >= (BASE_SIZE2) ? (mSize+(mSize>>1))
: (mSize >= 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 (mHashes.length > 0) {
            if (DEBUG) Log.d(TAG, "put: copy 0-" + mSize + " to 0");
            //特別注意這,是copy,而不是new,效率提升
            System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length);
            System.arraycopy(oarray, 0, mArray, 0, oarray.length);
        }
            //釋放無用空間,收縮數組
        freeArrays(ohashes, oarray, mSize);
    } 

ArrayMap用的是copy數據,所以效率相對要高。
最後說說使用場景,如果存儲數量在千級以下,可以考慮用ArrayMap代替HashMap,但要注意的是,ArrayMap要比HashMap慢。Android裏的Bundle內部就是ArrayMap,所以大家可以自行考慮使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章