SparseArray源码解析
No1:
Android官方推荐:当使用HashMap(K, V),如果K为整数类型时,使用SparseArray的效率更高.
No2:
HashMap是使用数组+链表的数据结构存储键值对,而SparseArray只是用了两个数组进行存储.
No3:
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
}
No4:
put函数的步骤:
1)通过二分查找算法,计算key的索引值.
2)如果索引值大于0,说明有key对应的value存在,直接替换value即可.
3)如果索引值小于0,对索引值取反,获取key应该插入的坐标i.
4)判断是否需要扩容:1.需要扩容,则先扩容; 2.不需要扩容,则利用System.arraycopy移动相应的元素,进行(key,value)键值对插入
最终用到了这个函数
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
No5:
delete操作只是根据二分算法查找出key对应的下标,然后将object[] value中的对应下标值设置为DELETED.
No6:
delete()函数中将被删除的key对应的value设置为DELETED,并设置gc标志mGarbage为ture,SparseArray是在put函数的时候执行了gc:
gc函数的原理:遍历一遍数组,将非DELETED资源全部移动到数组前面.
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);
}
No7:
SparseArray vs HashMap:
1)首先,这是两种完全不同的数据结构.SparseArray是两个数组:int[]和Object[], HashMap是数组+链表.
2)查找效率上: 首先,SparseArray不需要对key进行hash运算,并且通过二分查找保证查询效率为O(lgn).而HashMap在未冲突的情况下是O(1),冲突的情况下是O(n).
SparseArray源码解析的更多相关文章
- Android Handler机制(二)---MessageQueue源码解析
MessageQueue 1.变量 private final boolean mQuitAllowed;//表示MessageQueue是否允许退出 @SuppressWarnings(" ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- jQuery2.x源码解析(缓存篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...
- Spring IoC源码解析——Bean的创建和初始化
Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...
- jQuery2.x源码解析(构建篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...
- jQuery2.x源码解析(设计篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...
随机推荐
- Wannafly挑战赛21 E 未来城市规划
传送门 题目中给的信息很难直接维护,但是可以考虑一条边对答案的贡献 在以\(x\)为根的子树里,如果一条边\(i\)的权值为\(w_i\),这条边深度更深的端点为\(to_i\),那么这条边对这个子树 ...
- js sort方法根据数组中对象的某一个属性值进行排序
sort方法接收一个函数作为参数,这里嵌套一层函数用来接收对象属性名,其他部分代码与正常使用sort方法相同. var arr = [ {name:'zopp',age:0}, {name:'gpp' ...
- flask_restplus(1)- 未完成
快速开始 本指南假设您对Flask有一定的了解,并且您已经安装了Flask和Flask- restplus.如果没有,则按照安装部分中的步骤操作. 初始化 与其他所有扩展一样,您可以使用应用程序对象初 ...
- WebsphereMQ搭建集群
#https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1202_gaoly_mq/1202_gaoly_mq.ht ...
- 自定义el标签
编写java代码 package com.ycjk.common; public class FormatJSEltarg { public static String format(String s ...
- 转载:《理解OAuth 2.0》 阮一峰
原文:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛 ...
- 解决Idea运行testng套件无testoutput文件夹问题
说明:testNG的工程我是使用eclipse创建的,直接导入到idea中,运行test时不会生产test-output,只能在idea的控制台中查看运行结果,然后到处报告,经过不懈的百度终于找到怎么 ...
- PYTHON-函数的定义与调用,返回值,和参数
函数基础'''1. 什么是函数 具备某一功能的工具->函数 事先准备工具的过程--->函数的定义 遇到应用场景,拿来就用---->函数的调用 函数分类两大类: 1. 内置函数 2. ...
- OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- vue-router之路由钩子(组件内路由钩子必须在路由组件调用,子组件没用)
模式 vue-router中的模式选项主要在router实例化的时候进行定义的,如下 const router = new VueRouter({ mode: 'history', // 两种类型hi ...