- 浏览: 39596 次
- 性别:
- 来自: 北京
文章分类
最新评论
HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果。最近在做一个Android项目,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performance 警告。
意思就是说用SparseArray<E>来替代,以获取更好性能。老实说,对SparseArray并不熟悉,第一感觉应该是Android提供的一个类。按住Ctrl点击进入SparseArray的源码,果不其然,确定是Android提供的一个工具类。
单纯从字面上来理解,SparseArray指的是稀疏数组(Sparse array),所谓稀疏数组就是数组中大部分的内容值都未被使用(或都为零),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。
假设有一个9*7的数组,其内容如下:
在此数组中,共有63个空间,但却只使用了5个元素,造成58个元素空间的浪费。以下我们就使用稀疏数组重新来定义这个数组:
其中在稀疏数组中第一部分所记录的是原数组的列数和行数以及元素使用的个数、第二部分所记录的是原数组中元素的位置和内容。经过压缩之后,原来需要声明大小为63的数组,而使用压缩后,只需要声明大小为6*3的数组,仅需18个存储空间。
继续阅读SparseArray的源码,从构造方法我们可以看出,它和一般的List一样,可以预先设置容器大小,默认的大小是10:
1 |
public SparseArray() {
|
2 |
this ( 10 );
|
3 |
} |
4 |
5 |
public SparseArray( int initialCapacity) {
|
6 |
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
|
7 |
8 |
mKeys = new int [initialCapacity];
|
9 |
mValues = new Object[initialCapacity];
|
10 |
mSize = 0 ;
|
11 |
} |
再来看看它对数据的“增删改查”。
它有两个方法可以添加键值对:
1 |
public void put( int key, E value) {}
|
2 |
public void append( int key, E value){} |
有四个方法可以执行删除操作:
1 |
public void delete( int key) {}
|
2 |
public void remove( int key) {} //直接调用的delete(int key)
|
3 |
public void removeAt( int index){}
|
4 |
public void clear(){} |
修改数据起初以为只有setValueAt(int index, E value)可以修改数据,但后来发现put(int key, E value)也可以修改数据,我们查看put(int key, E value)的源码可知,在put数据之前,会先查找要put的数据是否已经存在,如果存在就是修改,不存在就添加。
1 |
public void put( int key, E value) {
|
2 |
int i = binarySearch(mKeys, 0 , mSize, key);
|
3 |
4 |
if (i >= 0 ) {
|
5 |
mValues[i] = value;
|
6 |
} else {
|
7 |
i = ~i;
|
8 |
9 |
if (i < mSize && mValues[i] == DELETED) {
|
10 |
mKeys[i] = key;
|
11 |
mValues[i] = value;
|
12 |
return ;
|
13 |
}
|
14 |
15 |
if (mGarbage && mSize >= mKeys.length) {
|
16 |
gc();
|
17 |
18 |
// Search again because indices may have changed.
|
19 |
i = ~binarySearch(mKeys, 0 , mSize, key);
|
20 |
}
|
21 |
………… |
所以,修改数据实际也有两种方法:
1 |
public void put(int key, E value) |
2 |
public void setValueAt(int index, E value) |
最后再来看看如何查找数据。有两个方法可以查询取值:
1 |
public E get(int key) |
2 |
public E get(int key, E valueIfKeyNotFound) |
其中get(int key)也只是调用了 get(int key,E valueIfKeyNotFound),最后一个从传参的变量名就能看出,传入的是找不到的时候返回的值.get(int key)当找不到的时候,默认返回null。
查看第几个位置的键:
1 |
public int keyAt(int index) |
有一点需要注意的是,查看键所在位置,由于是采用二分法查找键的位置,所以找不到时返回小于0的数值,而不是返回-1。返回的负值是表示它在找不到时所在的位置。
查看第几个位置的值:
1 |
public E valueAt( int index) |
查看值所在位置,没有的话返回-1:
1 |
public int indexOfValue(E value) |
最后,发现其核心就是折半查找函数(binarySearch),算法设计的很不错。
1 |
private static int binarySearch( int [] a, int start, int len, int key) {
|
2 |
int high = start + len, low = start - 1 , guess;
|
3 |
4 |
while (high - low > 1 ) {
|
5 |
guess = (high + low) / 2 ;
|
6 |
7 |
if (a[guess] < key)
|
8 |
low = guess;
|
9 |
else |
10 |
high = guess;
|
11 |
}
|
12 |
13 |
if (high == start + len)
|
14 |
return ~(start + len);
|
15 |
else if (a[high] == key)
|
16 |
return high;
|
17 |
else |
18 |
return ~high;
|
19 |
} |
相应的也有SparseBooleanArray,用来取代HashMap<Integer, Boolean>,SparseIntArray用来取代HashMap<Integer, Integer>,大家有兴趣的可以研究。
总结:SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的类,目的是提高效率,其核心是折半查找函数(binarySearch)。在Android中,当我们需要定义
1 |
HashMap<Integer, E> hashMap = new HashMap<Integer, E>(); |
时,我们可以使用如下的方式来取得更好的性能。
1 |
SparseArray<E> sparseArray = new SparseArray<E>(); |
注:
文中关于稀疏数组(Sparse array)的定义说明参照至:
http://hi.baidu.com/piaopiao_0423/item/d8cc2b99729f8380581461d1
发表评论
-
设置内存卡资源图片
2013-03-12 10:11 479String imageDir = Environment. ... -
android字体过长渐变效果
2013-01-30 15:59 663使用 android:singleLine="t ... -
自定义之checkbox
2013-01-08 09:16 614android中自定义checkbox大小和图片 (转) ... -
Android中Activity,View,Window之间的关系(转)
2012-12-03 09:11 11261.首先来看Activity中的attach()方法,在调用o ... -
Dialog的dismiss和cancel 区别 (转)
2012-12-03 09:13 1845Dialog的dismiss和cancel AlertDial ... -
android应用程序适配在不同的手机上(转)
2012-12-03 09:15 487如何将一个应用程序适 ... -
android 堆栈 清理 (转)
2012-12-03 09:16 665启动任务 当一个activity ... -
Android权限共享UID(转)
2012-12-03 09:16 544共享UID 安装在设备中 ... -
ViewPager+TabHost 实现选项卡页面间滑动(转)
2012-12-04 09:19 915转自http://flycatdeng.iteye.com/b ... -
android扫描商品条形码
2012-12-04 09:19 995(转自http://marshal.easymorse.com ... -
基于Android平台的NFC技术的应用实现 (转)
2012-12-04 09:20 1397转自http://1679554191.iteye.com/b ... -
Android API包名及包的功能的中文介绍
2012-11-30 09:38 972android 包含应用平台和在定义应用程序所用到and ... -
Android 自动解锁 KeyguardManager(键盘管理器)(转)
2012-11-30 09:39 931写一个Activity启动该服务即可,用一个线程开启服务, ... -
Android之Service与IntentService的比较 .
2012-11-30 09:41 676转自http://blog.csdn.net/zhf19890 ... -
AlarmManager的使用
2012-11-30 09:42 666AlarmManager的作用文档中的解释是:在特定的时刻为 ... -
ActivityGroup之生命周期
2012-12-04 09:20 782Activity的生命周期已经 ... -
ActivityGroup之切换activity
2012-12-04 09:20 661前言 在一个主界面中做Activity切换一般都会用T ... -
Android SurviceView的触控和轨迹球事件 .
2012-12-05 14:10 1056SurfaceView 的触控和轨迹球事件 1,改开始什 ... -
home键屏蔽
2012-12-05 14:11 6181. 在activity中加上这段代码(重写onAttache ... -
彻底删除某个APK的方法
2012-12-05 14:11 10631. 连接ADB, 执行adb remount 2. 执行a ...
相关推荐
android ActivityManagerService 学习资料
前端开源库-happn-random-activity-generatorHAPPN随机活动生成器,生成随机活动
102.Android面试之---讲一下你对Activity的了解(面试必问的).1
3-12-5(Activity跳转与操作).7z
t-l-51729-little-red-riding-hood-traditional-tales-differentiated-reading-comprehension-activity.pdf
RuoYi-process多模块activity工作流项目代码;
这个工程是使用activity-alias创建应用的别名的Deom,有需要的可以下载
前两年IOS应用源码-主要是用于毕业设计学习的。
iBiliPlayer-html5_activity_game_20221205_wzryfyt_wzry_yhjh.apk
Activity for eclipse plugin .Version:5.9.3 下载后直接解压至dropins 目录下就能正常工作 ,然后启动 eclipse -clean
cordova-plugins-activity cordova调用安卓原生activity插件 使用简介 JS端使用方式 //sendData表示要从js端发送到原生activity的数据,需用json对象传输 var sendData = { id:10001, name:"Simon", age:28 }; ...
Android高级应用源码-Activity切换动画--模糊、水波纹、折叠效果.zip
实验二 Activity组件通信 一、实验目的及要求 (1) 掌握显示启动和隐式启动的方式 (2) 掌握Activity间的数据通信 二、实验内容及步骤 任务:根据下述要求实现对应程序 1、 完成启动界面的设计,要求采用合理布局...
在应用程序正常时,当前的Activity有时会因为其他可视化组件阻塞(obstructed)而导致Activity暂停。例如,当打开一个半透明(semi-transparent)的活动(比如,对话框),先前的Activity就会暂停。
pipeline applied to an activity-rich video dataset. In contrast to traditional work on multi-target pedestrian tracking where people are largely assumed to be upright, we use an activity-rich dataset ...
Android-DragDismissActivity:滑动取消Activity
activiti,符合BPMN2.0标准。此为activiti5.18源码,参考使用,读源码是好习惯。
Voice activity detection (VAD) toolkit including DNN, bDNN, LSTM and ACAM based VAD
Android学习笔记-Activity篇 Contents Android学习笔记-Activity篇 1 一、activity创建: 1 二、在manifest.xml中声明activity: 1 三、启动activity 1 3.1 启动不带返回结果的Activity 1 3.2 启动带有返回结果的...
@stoe/octokit-plugin-org-activity 用于获取给定 GitHub 组织的成员活动的 Octokit 插件安装$ npm install @stoe/octokit-plugin-org-activity用法个人访问令牌认证: const { Octokit } = require ( '@octokit/...