安卓开发-工具类的使用

SparseArray

中文名字是稀疏数组。

SparseArrays map integers to Objects. Unlike a normal array of Objects, there can be gaps in the indices. It is intended to be more efficient than using a HashMap to map Integers to Objects.

从它的源码随处可以看到,它采用了二分法(binarySearch)来存储和查找数据。

看了上面一点资料之后,我并不认为它的性能会比Hashmap的要好。hashmap毕竟能够大约O(1)的时间查找到对象。而这个稀疏数组却要二分才能找到目标。

-------------------------------

使用SparseArray有两个好处。

1、使用hashmap的时候,我们需要这么样声明:

HashMap<Integer, String> m=new HashMap<Integer, String>();

从上面这行代码以看到,map中,将一个整数映射到一个Object的时候,是需要自动装箱拆箱的(性能的浪费)。而SparseArray不需要。SparseArray的key直接就是int。

看key的声明:

private int[] mKeys;

2、手持设备一般是内存受限的。Hashmap虽然查找性能好,但是map有一个问题就是浪费内存。而SparseArray虽然查找效率是O(logn)的,但是,,,,先看一下SparseArray的源码中gc函数:

 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);
    }

这个函数“回收”SparseArray中已经“DELETED”的元素。设置它们为NULL。从这点我们可以看到,SparseArray在删除元素的时候,并不是真正的删除。而是将相应的位置上置为“DELETED”,然后在某个时间再去“gc”,设置为null。这就是为什么SparseArray的api上描述,Unlike a normal array of Objects, there can be gaps in the indices,这些gaps就是gc的时候设置为null的地方了。gc的时候,会将SparseArray中维护的数组内容向前移动(for语句中的那三句赋值操作)。这样就把gaps消除了。每次gc,都能把之前设置为DELETED的部分消除。那么,数组后边的元素移动到前面了,后面空出来的空间怎么处理?从它源码中也是随处可看到这么一句:

int n = ArrayUtils.idealIntArraySize(mSize + 1);

这句话就是分配数组大小。然后在put等添加操作的时候,用新申请的数组放置元素,原来的数组等待JVM来回收。

下面看一下idealIntArraySize函数的实现:

所以每次ArrayUtils分配数组大小的时候,会“酌情”考虑比need多分配一些空间。从而让数组不是那么容易就要因为增加内容而再次分配空间。

-----------------------------------------------------

另外要注意的是,它是线程不安全的。

相对map来说,SparseArray能节省内存。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值