HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果。最近在做一个Android项目,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performance 警告。

意思就是说用SparseArray 来替代,以获取更好性能。老实说,对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. public SparseArray(int initialCapacity) {
  5. initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
  6. mKeys = new int[initialCapacity];
  7. mValues = new Object[initialCapacity];
  8. mSize = 0;
  9. }

再来看看它对数据的”增删改查”。

它有两个方法可以添加键值对:

  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. if (i > = 0) {
  4. mValues[i] = value;
  5. } else {
  6. i = ~i;
  7. if (i < mSize &amp;&amp; mValues[i] == DELETED) {
  8. mKeys[i] = key;
  9. mValues[i] = value;
  10. return;
  11. }
  12. if (mGarbage &amp;&amp; mSize > = mKeys.length) {
  13. gc();
  14. // Search again because indices may have changed.
  15. i = ~binarySearch(mKeys, 0, mSize, key);
  16. }
  17. …………

所以,修改数据实际也有两种方法:

  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。

查看第几个位置的键:public int keyAt(int index)
有一点需要注意的是,查看键所在位置,由于是采用二分法查找键的位置,所以找不到时返回小于0的数值,而不是返回-1。返回的负值是表示它在找不到时所在的位置。

查看第几个位置的值:
public E valueAt(int index)
查看值所在位置,没有的话返回-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. while (high - low > 1) {
  4. guess = (high + low) / 2;
  5. if (a[guess] < key)
  6. low = guess;
  7. else
  8. high = guess;
  9. }
  10. if (high == start + len)
  11. return ~(start + len);
  12. else if (a[high] == key)
  13. return high;
  14. else
  15. return ~high;
  16. }

相应的也有SparseBooleanArray,用来取代HashMap <integer, boolean="">,SparseIntArray用来取代HashMap <integer, integer="">,大家有兴趣的可以研究。

总结:
SparseArray是android里为 <interger,object>这样的Hashmap而专门写的类,目的是提高效率,其核心是折半查找函数(binarySearch)。在Android中,当我们需要定义
HashMap <Integer, E> hashMap = new HashMap <Integer, E> ();
时,我们可以使用如下的方式来取得更好的性能.
SparseArray <E> sparseArray = new SparseArray <E> ();

android:应用性能优化SparseArray的更多相关文章

  1. Android 性能优化 SparseArray【转载】

    原文地址:Android学习笔记之性能优化SparseArray 学习内容: 1.Android中SparseArray的使用..   昨天研究完横向二级菜单,发现其中使用了SparseArray去替 ...

  2. Android应用性能优化(转)

    人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然连贯(帧率为24fps),用手机当然也需要感知屏幕操作的连贯性(尤其是动画过度),所以Android索性就把达到这 ...

  3. android app性能优化大汇总

    这里根据网络上各位大神已经总结的知识内容做一个大汇总,作为记录,方便后续“温故知新”. 性能指标: (1)使用流畅度:  图片处理器每秒刷新的帧数(FPS),可用来指示页面是否平滑的渲染.高的帧率可以 ...

  4. Android客户端性能优化(魅族资深工程师毫无保留奉献)

    本文由魅族科技有限公司资深Android开发工程师degao(嵌入式企鹅圈原创团队成员)撰写,是degao在嵌入式企鹅圈发表的第一篇原创文章,毫无保留地总结分享其在领导魅族多个项目开发中的Androi ...

  5. Android APP 性能优化的一些思考

    说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才 ...

  6. 包建强的培训课程(9):Android App性能优化

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  7. Android app 性能优化的思考--性能卡顿不好的原因在哪?

    说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才 ...

  8. Android开发性能优化总结(一)

    安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户. 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流. ...

  9. Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手

    图片加载性能优化永远是Android领域中一个无法绕过的话题,经过数年的发展,涌现了很多成熟的图片加载开源库,比如Fresco.Picasso.UIL等等,使得图片加载不再是一个头疼的问题,并且大幅降 ...

随机推荐

  1. position:absolute在IE8浏览器下无法显示正确位置

      在网页head下添加 <meta http-equiv="x-ua-compatible" content="ie=8" />

  2. .net core定时任务

    1.HangFire HangFire官网 Hangfire项目实践分享 :  讲解的比较详细 2.Quartz.NET https://www.cnblogs.com/best/p/7658573. ...

  3. JS高级 - 面向对象4(json方式面向对象)

    把方法包在一个Json里 var p1 = { name: "唐三", sex: "男", dreamdu: { URL: "www.dreamdu. ...

  4. 写给Android开发者的混淆使用手册

    转自:http://huihui.name/2016/10/23/%E5%86%99%E7%BB%99Android%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E6%B7 ...

  5. Codeforces Round #321 (Div. 2) E - Kefa and Watch

    题目大意:给你一个由0-9组成的字符串,有m个询问,两种操作,第一种将l到r的字符全部变成c,第二种问l到r这段 字符串的循环节是不是d. 思路:首先我们要知道怎么判断字符串的循环节的长度是不是d,如 ...

  6. BZOJ3674 可持久化并查集加强版 可持久化 并查集

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3674 题意概括 n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的 ...

  7. 【Java】 剑指offer(53-3) 数组中数值和下标相等的元素

      本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 假设一个单调递增的数组里的每个元素都是整数并且是唯一的.请编程 ...

  8. P1510 精卫填海

    P1510 精卫填海二分答案二分背包容量,判断能否满足v.判断的话就跑01背包就好了. #include<iostream> #include<cstdio> #include ...

  9. Spring框架学习03——Spring Bean 的详解

    1.Bean 的配置 Spring可以看做一个大型工厂,用于生产和管理Spring容器中的Bean,Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置 ...

  10. spring aop简单理解

    aop原理是spring帮我们封装了动态代理,然后我们只管写具体的业务,我们将公共业务也写到具体的一个类中并实现spring为我们提供的对应要连接切入哪个位置的接口,然后再xml中配置它们的关系即可. ...