public void put(int key, E value) {
//先调用二分法查询该key在数组中的位置
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (i >= 0) {
//大于0说明已经存在数组中,可以直接赋值
mValues[i] = value;
} else {
//小于0说明这是一个新的键值对,且它应该插在数组中的第i个位置
i = ~i;
//根据DELETED来查询当前位置的值是否已经被删除
if (i < mSize && mValues[i] == DELETED) {
mKeys[i] = key;
mValues[i] = value;
return;
}
//如果当前容量已满
if (mGarbage && mSize >= mKeys.length) {
//回收无效空间
gc();
// Search again because indices may have changed.
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
}
mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
}
可以看到,SparseArray
会先调用二分法去查询key应该存放在数组中的位置,所以SparseArray
的key数组一定是有序排列的,然后会用一个DELETED
来作为当前位置的元素是否已经被删除,DELETED
会在调用remove
移除元素的时候赋给对应位置Value,如下:
public void remove(int key) {
delete(key);
}
public void delete(int key) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (i >= 0) {
if (mValues[i] != DELETED) {
mValues[i] = DELETED;
mGarbage = true;
}
}
}
SparseArray
通过这个来作为它压缩空间的一个标志(即该位置可不可以被回收),这样子也进一步节省了空间。
从刚才可以看出,无论是SparseArray的put
还是delete
(其实其他操作比如get
也都是通过二分法寻找下标),都是通过二分法去查询这个key应该被存放的位置。而HashMap在插入的时候,不需要去遍历整个集合,而是直接通过hash计算出位置插入。所以在插入效率上,SparseArray会比HashMap稍慢一些,但在数据量不大的情况下,两者的差别不大。
结语
SparseArray
与HashMap
相比,最大的优势在于内存方面,无论数据量级大小如何,SparseArray
所占用的内存都会比HashMap小,在Android中内存是极为重要的,所以在需要保存<Integer,Object>键值对的场景中,推荐使用SparseArray
替换HashMap
。换句话说,SparseArray
是Android中为<Integer,Object>这样的HashMap专门写的类,它避开了自动装箱并且压缩稀疏数组,目的就是为了节省内存。
另外,Android还提供了其他几种类似的集合类:SparseIntArray
、SparseBooleanArray
、SparseLongArray
,可以支持存储<Integer,Integer>、<Integer,Boolean>、<Integer,Long>的数据类型,也就是同时让Value也避开了装箱过程,进一步优化。
作者;Android小Y
链接;https://www.jianshu.com/p/1828f14d7955
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
最后
Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。
人生不可能一帆风顺,有高峰自然有低谷,要相信,那些打不倒我们的,终将使我们更强大,要做自己的摆渡人。
资源持续更新中,欢迎大家一起学习和探讨。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中…(img-NBDyKuM0-1712781431108)]