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
2
3
4
5
6
7
8
9
10
11

    public SparseArray(){
        this(10);
    }
    public SparseArray(intinitialCapacity){
        initialCapacity=ArrayUtils.idealIntArraySize(initialCapacity);
        mKeys=new int[initialCapacity];
        mValues=new Object[initialCapacity];
        mSize=0;
    }

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

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

1
2

public voidput(intkey,Evalue){}
public voidappend(intkey,Evalue){}

有四个方法可以执行删除操作:

1
2
3
4

public voiddelete(intkey){}
public voidremove(intkey){}//直接调用的delete(int key)
public voidremoveAt(intindex){}
public voidclear(){}

修 改数据起初以为只有setValueAt(int index, E value)可以修改数据,但后来发现put(int key, E value)也可以修改数据,我们查看put(int key, E value)的源码可知,在put数据之前,会先查找要put的数据是否已经存在,如果存在就是修改,不存在就添加。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

    public voidput(intkey,Evalue){
        inti=binarySearch(mKeys,0,mSize,key);
        if(i&gt;=0){
            mValues[i]=value;
        }else{
            i=~i;
            if(i&lt;mSize&amp;&amp;mValues[i]==DELETED){
                mKeys[i]=key;
                mValues[i]=value;
                return;
            }
            if(mGarbage&amp;&amp;mSize&gt;=mKeys.length){
                gc();
                // Search again because indices may have changed.
                i=~binarySearch(mKeys,0,mSize,key);
            }
            …………

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

1
2

public voidput(intkey,Evalue)
public voidsetValueAt(intindex,Evalue)

最后再来看看如何查找数据。有两个方法可以查询取值:

1
2

publicEget(intkey)
publicEget(intkey,EvalueIfKeyNotFound)

其中get(int key)也只是调用了 get(int key,E valueIfKeyNotFound),最后一个从传参的变量名就能看出,传入的是找不到的时候返回的值.get(int key)当找不到的时候,默认返回null。

查看第几个位置的键:

1
public intkeyAt(intindex)

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

查看第几个位置的值:

1
publicEvalueAt(intindex)

查看值所在位置,没有的话返回-1:

1
public intindexOfValue(Evalue)

最后,发现其核心就是折半查找函数(binarySearch),算法设计的很不错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

    private staticintbinarySearch(int[] a,intstart,intlen,intkey){
        inthigh=start+len,low=start-1,guess;
        while(high-low&gt;1){
            guess=(high+low)/2;
            if(a[guess]&lt;key)
                low=guess;
            else
                high=guess;
        }
        if(high==start+len)
            return~(start+len);
        elseif(a[high]==key)
            returnhigh;
        else
            return~high;
    }

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

总结:SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的类,目的是提高效率,其核心是折半查找函数(binarySearch)。在Android中,当我们需要定义

1
HashMap<Integer,E>hashMap=newHashMap<Integer,E>();

时,我们可以使用如下的方式来取得更好的性能.

1
SparseArray<E>sparseArray=newSparseArray<E>();

 注:

文中关于稀疏数组(Sparse array)的定义说明参照至:

http://hi.baidu.com/piaopiao_0423/item/d8cc2b99729f8380581461d1

转载于:https://www.cnblogs.com/royi123/archive/2013/06/02/3114202.html

Android应用性能优化之使用SparseArray替代HashMap(转)相关推荐

  1. Android应用性能优化之使用SparseArray替代HashMap

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

  2. HashMap can be replaced with SparseArray--Android应用性能优化之使用SparseArray替代HashMap

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

  3. android 应用性能优化1

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  4. Android应用性能优化——学习心得

    Android应用性能优化--学习心得 Android应用性能优化这门课分为内存优化.视图优化.电量优化.Bitmap优化.其他优化等五大部分,下面这对这五大部分的学习能容做一下总结: 一. 内存优化 ...

  5. Android APP性能优化

    转载自:https://www.cnblogs.com/qwangxiao/p/8727229.html Android APP性能优化(最新总结) 导语 安卓大军浩浩荡荡,发展已近十个年头,技术优化 ...

  6. Android WebView 性能优化

    原文出处:http://motalks.cn/2016/09/11/Android-WebView-JavaScript-3/ WebView相关阅读 Android WebView 和 javaSc ...

  7. Android APP性能优化(一)

    Android APP性能优化(最新总结) 安卓大军浩浩荡荡,发展已近十个年头,技术优化日异月新,如今Android 8.0 Oreo 都发布了,Android系统性能已经非常流畅了.但是,到了各大厂 ...

  8. Android应用性能优化之优化列表头像过度绘制[一]

    为什么80%的码农都做不了架构师?>>>    操作的是否顺畅.卡顿,决定着整体的流畅程度. 事实上android跟iphone的差别,个人觉得很大程度上决定于流畅程度,无论是动画, ...

  9. C语言性能优化书籍,Android应用性能优化 (埃尔韦) 中文PDF扫描版

    <android应用性能优化>主要介绍如何调优android 应用,以使应用更健壮并提高其执行速度.内容包括用java.ndk 优化应用,充分利用内存以使性能最大化,尽最大可能节省电量,何 ...

最新文章

  1. 腾讯天衍实验室联合微众银行研发医疗联邦学习 AI利器让脑卒中预测准确率达80%
  2. Ubuntu 调试的时候,不能查看变量值
  3. _Blank主页——个人浏览器主页定制
  4. 华为鸿蒙系统正式拜拜,从“哄蒙”到“鸿蒙”,现在,正式对华为鸿蒙OS说你好!...
  5. 2020教育OMO模式落地应用研究报告
  6. Eclipse InstaSearch搜索词法 (很多并不支持)
  7. 自定义曲线_Qt编写的项目作品17-自定义曲线图柱状图
  8. 基于CSRF的XSS攻击
  9. 服务器美萍管理系统,美萍服装管理软件互联网版(Web会员管理软件、连锁店会员卡管理系统、B/S版连锁会员管理系统)...
  10. 数据分析面试【统计学】-----假设检验知识点归纳
  11. Amesim学习——弹球仿真
  12. MySQL基本架构示意图
  13. python高级练习题:转换所有的案件!【难度:3级】--景越Python编程实例训练营,不同难度Python习题,适合自学Python的新手进阶
  14. python的PIL库部分模块函数
  15. SpringBoot使用druid的密码加密
  16. C#里封装 继承 多态(包教包会)
  17. JavaEE架构之传统三层架构,集群架构,分布式架构,微服务架构
  18. Android【Socket通讯】
  19. Java观察者模式事件委托(通过dota和王者荣耀故事讲解)
  20. 本特利振动传感器123617-XXX-XXX-05-02-00 MOD:159811-000-130

热门文章

  1. 问题 | CondaHTTPError: HTTP 404 NOT FOUND for url
  2. oracle11g imp性能,怎么最快地把本机的oracle11g数据导入xe
  3. 简析.NET Core 以及与 .NET Framework的关系
  4. oracle 性别 函数索引优化,oracle优化记录4_改写函数索引列
  5. linux .net core java_仅在.NET Core 2.0运行时的Linux上缺少运行时存储库错误
  6. 工业用微型计算机(20)-指令系统(15)
  7. access开发精要(7)-定位记录、查找空值
  8. 【论文解读】基于图卷积的价格感知推荐
  9. 真相了!算法工程师的一天
  10. 0402互联网新闻 | 首批进口游戏版号下放,网易腾讯获批;“少年得到”完成数千万元A轮融资...