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

意思就是说用SparseArray <E> 来替代,以获取更好性能。老实说,对SparseArray并不熟悉,第一感觉应该是Android提供的一个类。按住Ctrl点击进入SparseArray的源码,果不其然,确定是Android提供的一个工具类。

单纯从字面上来理解,SparseArray指的是稀疏数组(Sparse array) ,所谓稀疏数组就是数组中大部分的内容值都未被使用(或都为零),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。

假设有一个9*7的数组,其内容如下:

其中在稀疏数组中第一部分所记录的是原数组的列数和行数以及元素使用的个数、第二部分所记录的是原数组中元素的位置和内容。经过压缩之后,原来需要声明大小为63的数组,而使用压缩后,只需要声明大小为6*3的数组,仅需18个存储空间。

继续阅读SparseArray的源码,从构造方法我们可以看出,它和一般的List一样,可以预先设置容器大小,默认的大小是10:

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

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

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

 public void put(int key, E value) {}public void append(int key, E value){}

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

 public void delete(int key) {}public void remove(int key) {} //直接调用的delete(int key)public void removeAt(int index){}public void clear(){}

(3)修改操作

修改数据起初以为只有setValueAt(int index, E value)可以修改数据,但后来发现put(int key, E value)也可以修改数据,我们查看put(int key, E value)的源码可知,在put数据之前,会先查找要put的数据是否已经存在,如果存在就是修改,不存在就添加。
public void put(int key, E value) {int i = binarySearch(mKeys, 0, mSize, key);if (i > = 0) {mValues[i] = value;} else {i = ~i;if (i  < mSize && mValues[i] == DELETED) {mKeys[i] = key;mValues[i] = value;return;}if (mGarbage && mSize > = mKeys.length) {gc();// Search again because indices may have changed.i = ~binarySearch(mKeys, 0, mSize, key);}…………

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

 public void put(int key, E value)public void setValueAt(int index, E value)

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

 public E get(int key)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),算法设计的很不错。

private static int binarySearch(int[] a, int start, int len, int key) {int high = start + len, low = start - 1, guess;while (high - low >  1) {guess = (high + low) / 2;if (a[guess]  < key)low = guess;elsehigh = guess;}if (high == start + len)return ~(start + len);else if (a[high] == key)return high;elsereturn ~high;}

相应的也有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> ();

原文URL:https://liuzhichao.com/p/832.html

=====================

SparseArray

extends Object
implements Cloneable

java.lang.Object
   ↳ android.util.SparseArray<E>

Class Overview


SparseArrays map integers to Objects. Unlike a normal array of Objects, there can be gaps in the indices. It is intended to be more memory efficient than using a HashMap to map Integers to Objects, both because it avoids auto-boxing keys and its data structure doesn't rely on an extra entry object for each mapping.

Note that this container keeps its mappings in an array data structure, using a binary search to find keys.The implementation is not intended to be appropriate for data structures that may contain large numbers of items.It is generally slower than a traditional HashMap, since lookups require a binary search and adds and removes require inserting and deleting entries in the array. For containers holding up to hundreds of items, the performance difference is not significant, less than 50%.

To help with performance, the container includes an optimization when removing keys: instead of compacting its array immediately, it leaves the removed entry marked as deleted. The entry can then be re-used for the same key, or compacted later in a single garbage collection step of all removed entries. This garbage collection will need to be performed at any time the array needs to be grown or the the map size or entry values are retrieved.

It is possible to iterate over the items in this container using keyAt(int) and valueAt(int). Iterating over the keys using keyAt(int) with values of the index will return the keys in ascending order, or the values corresponding to the keys in ascending order in the case of valueAt(int).

摘自:http://developer.android.com/reference/android/util/SparseArray.html

HashMap can be replaced with SparseArray--Android应用性能优化之使用SparseArray替代HashMap相关推荐

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

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

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

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

  3. android 应用性能优化1

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

  4. Android应用性能优化最佳实践.

    移动开发 Android应用性能优化最佳实践 罗彧成 著 图书在版编目(CIP)数据 Android应用性能优化最佳实践 / 罗彧成著. -北京:机械工业出版社,2017.1 (移动开发) ISBN ...

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

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

  6. Android App 性能优化之稳定性

    Android App性能优化之稳定性问题分类 1. ANR 2. Crash 3. 应用退出 1. ANR ANR(Application Not Responding 应用程序无响应) 1.1大致 ...

  7. Android APP性能优化

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

  8. Android WebView 性能优化

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

  9. Android APP性能优化(一)

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

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

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

最新文章

  1. 一键数据分析自动化特征工程!
  2. soapui工具_python接口自动化(四)--接口测试工具介绍(详解)
  3. matlab中图像太大,图像处理:算法在MATLAB中耗时太长
  4. 跨链(2)跨链技术“侧链(Sidechains)”
  5. 3_11 InterpreterMode 解释器模式
  6. 工控机改装家庭智能中心--命令行配置无线wifi
  7. php获取html中文本框内容_小猿圈Python入门之批量获取html内body内容的方法
  8. 设计模式的C语言应用-访问者模式-第九章
  9. springcloud 高可用的服务注册中心
  10. Xml遍历某一节点值
  11. ubuntu20.04安装有道词典
  12. stm32 USB HID多点触摸屏上报安卓触摸信号
  13. 数据分析可视化- 十三朝古都西安
  14. nodejs+vue微信小程序的饭店外卖点餐平台系统
  15. 关于Amazon AWS —— 免费的午餐不好吃
  16. python导包和魔幻方法
  17. Wt(C++ Web) 源码编译以及cmake配置
  18. 解决win10 VirtualBox无法启动(VERR_NEM_VM_CREATE_FAILED)/VMware Workstation 与 Device/Credential Guard 不兼容
  19. 2017.10.16 装箱和拆箱﹑火星车的升级
  20. python——偏函数的使用

热门文章

  1. Err:query must begin with SELECT or FROM
  2. mkdir: cannot create directory ‘/soft/hadoop-2.7.3/logs’: Permission denied问题
  3. linux简单文件管理命令的使用
  4. .Net中XML,JSON的几种处理方式
  5. HTML-通知公告Tips
  6. leetcode 之Single Number(13)
  7. 漂亮的页面向导和Tab插件(Jquery)
  8. [分际]如何使用EVENTLOG类操作日志
  9. 洛谷 2585 [ZJOI2006]三色二叉树——树形dp
  10. python nose测试框架全面介绍十---用例的跳过