栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

SparseArray读源码

SparseArray读源码

1.将整数映射成对象(键值对),因为他不需要类似于HashMap进行装箱拆箱操作,所以内存效率优于HashMap;
2.使用二分法对于关键字进行查找(升序排列:类注释可知)

 
    public E get(int key) {
        return get(key, null);
    }

    
    @SuppressWarnings("unchecked")
    public E get(int key, E valueIfKeyNotFound) {
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);

        if (i < 0 || mValues[i] == DELETED) {
            return valueIfKeyNotFound;
        } else {
            return (E) mValues[i];
        }
    }


class ContainerHelpers {

    // This is Arrays.binarySearch(), but doesn't do any argument validation.
    static int binarySearch(int[] array, int size, int value) {
        int lo = 0;
        int hi = size - 1;

        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final int midVal = array[mid];

            if (midVal < value) {
                lo = mid + 1;
            } else if (midVal > value) {
                hi = mid - 1;
            } else {
                return mid;  // value found
            }
        }
        return ~lo;  // value not present
    }

    static int binarySearch(long[] array, int size, long value) {
        int lo = 0;
        int hi = size - 1;

        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final long midVal = array[mid];

            if (midVal < value) {
                lo = mid + 1;
            } else if (midVal > value) {
                hi = mid - 1;
            } else {
                return mid;  // value found
            }
        }
        return ~lo;  // value not present
    }
}

3.由于Key和Value是通过数组存储的,所以,如果需要进行增删改查操作,那么就需要真实的进行移位删除操作,参考数组的增删改查,因此,会产生大量的性能开销,为此,故采用了延迟删除的操作

    @UnsupportedAppUsage(maxTargetSdk = 28) // Use keyAt(int)
    private int[] mKeys;
    @UnsupportedAppUsage(maxTargetSdk = 28) // Use valueAt(int), setValueAt(int, E)
    private Object[] mValues;


4.延迟删除,对于需要删除的操作,先把需要删除的元素标记起来,不做真正的删除,待到后续GC处理
5.通过查看GC源码可以得知,对于需要删除的已经被标记删除的元素,在gc方法处理时,也不会被真正的删除掉,但会处理原SparseArray的长度size,使需要删除的元素(延迟删除元素)在size以外,故永远不会被访问到,如果后续需要添加新的元素时,会被添加的元素覆盖掉

    private void gc() {
        // Log.e("SparseArray", "gc start with " + mSize);

        int n = mSize;
        int o = 0;
        int[] keys = mKeys;
        Object[] values = mValues;

        for (int i = 0; i < n; i++) {
            Object val = values[i];

            if (val != DELETED) {
                if (i != o) {
                    keys[o] = keys[i];
                    values[o] = val;
                    values[i] = null;
                }

                o++;
            }
        }

        mGarbage = false;
        mSize = o;

        // Log.e("SparseArray", "gc end with " + mSize);
    }

 

之前没打算写,后来觉得,反正自己也记不住,不如写下来,自己忘了还能有个地方找,也不指望能帮到人,就只为能帮到我自己

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/278531.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号