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. 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 && mValues[i] == DELETED) {
  8. mKeys[i] = key;
  9. mValues[i] = value;
  10. return;
  11. }
  12. if (mGarbage && 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。

查看第几个位置的键:

  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, intkey) {
2     inthigh = 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     elseif (a[high] == key)
16         returnhigh;
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>();

性能优化:使用SparseArray代替HashMap<Integer,Object>(转)的更多相关文章

  1. Android 开发性能优化之SparseArray(三)

    SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch) pr ...

  2. Android 开发性能优化之SparseArray(一)

    多数Android开发者都知道在Android中可以使用HashMap来映射一种对应关系,在java开发中HashMap也算是一种很重要的数据存储结构.然后很多人在Android开发中多数都会用Has ...

  3. Android 开发性能优化之SparseArray(二)

    一.SparseIntArray API SparseIntArrays map integers to integers.  Unlike a normal array of integers, t ...

  4. 关于Android中ArrayMap/SparseArray比HashMap性能好的深入研究

    由于网上有朋友对于这个问题已经有了很详细的研究,所以我就不班门弄斧了: 转载于:http://android-performance.com/android/2014/02/10/android-sp ...

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

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

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

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

  7. Android学习笔记之性能优化SparseArray

    PS:终于考完试了.来一发.微机原理充满了危机.不过好在数据库89分,还是非常欣慰的. 学习内容: 1.Android中SparseArray的使用..   昨天研究完横向二级菜单,发现其中使用了Sp ...

  8. android:应用性能优化SparseArray

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

  9. SparseArray替代HashMap来提高性能

    SparseArray是 Android框架独有的类,在标准的JDK中不存在这个类.它要比 HashMap 节省内存,某些情况下比HashMap性能更好,按照官方问答的解释,主要是因为SparseAr ...

随机推荐

  1. Jquery 较好的效果

    仿google图片效果图片展示相册(jquery)的演示页面 产品相册展示插件slideshow多图可翻页 懒人建站 Jquery分享A Jquery分享B Jquery分享C Jquery分享D

  2. CSS 实现图片灰度效果

    非原创-从网上收索出来的文章 CSS实现图片灰度效果就是通过CSS样式让彩色图片呈现为灰色,相当于把一张图像的颜色模式调整为灰度,CSS可以通过以下几种方法来实现灰度效果. 方式1. IE滤镜 img ...

  3. 【51Nod】1273 旅行计划 树上贪心

    [题目]51Nod 1273 旅行计划 [题意]给定n个点的树和出发点k,要求每次选择一个目的地旅行后返回,使得路径上未访问过的点最多(相同取编号最小),旅行后路径上所有点视为访问过,求旅行方案.\( ...

  4. 各种卷积类型Convolution

    从最开始的卷积层,发展至今,卷积已不再是当初的卷积,而是一个研究方向.在反卷积这篇博客中,介绍了一些常见的卷积的关系,本篇博客就是要梳理这些有趣的卷积结构. 阅读本篇博客之前,建议将这篇博客结合在一起 ...

  5. 《区块链100问》第13集:比特币和Q币有哪些不同?

    比特币是一种去中心化的数字资产,没有发行主体.Q币是由腾讯公司发行的电子货币,类似于电子积分,其实不是货币. Q币需要有中心化的发行机构,Q币因为腾讯公司的信用背书,才能被认可和使用.使用范围也局限在 ...

  6. [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现

    [LeetCode] Candy (分糖果),时间复杂度O(n),空间复杂度为O(1),且只需遍历一次的实现 原题: There are N children standing in a line. ...

  7. git 修改已提交的注释

    在git中,其commit提供了一个--amend参数,可以修改最后一次提交的信息 修改最后一次提交注释 git commit --amend 然后在出来的编辑界面,直接编辑注释的信息,保存退出 gi ...

  8. NET调用Com组件事例

    http://blog.csdn.net/shizhiyingnj/article/details/1507948 在程序设计中,往往通过键盘的某个按键来完成相关操作! 下面就来说明如何实现: 1.引 ...

  9. Centos: -bash: unzip: command not found

    安装命令:yum install -y unzip zip 同时安装unzip和zip

  10. python基础--模块使用

      一:模块介绍 模块分为三种: 自定义模块 内置标准模块(又称标准库) 开源模块 自定义模块使用 # -*- coding:utf-8 -*- __author__ = 'shisanjun' &q ...