(HashMap,SparseArray,ArrayMap)
来源:互联网 发布:js数组添加值 编辑:程序博客网 时间:2024/06/10 00:51
程序内存的管理是否合理高效对应用的性能有着很大的影响,有的时候对容器的使用不当也会导致内存管理效率低下。Android为移动操作系统特意编写了一些更加高效的容器,例如SparseArray,ArrayMap。
我们经常会使用到HashMap这个容器,它非常好用,但是却很占用内存。
HashMap
HashMap内部是使用一个默认容量为16的数组来存储数据的,而数组中每一个元素却又是一个链表的头结点,所以,更准确的来说,HashMap内部存储结构是使用哈希表的拉链结构(数组+链表)这种存储数据的方法叫做拉链法
我们知道HashMap中默认的存储大小就是一个容量为16的数组,所以当我们创建出一个HashMap对象时,即使里面没有任何元素,也要分别一块内存空间给它,而且,我们再不断的向HashMap里put数据时,当达到一定的容量限制时(这个容量满足这样的一个关系时候将会扩容:HashMap中的数据量>容量*加载因子,而HashMap中默认的加载因子是0.75),HashMap的空间将会扩大,而且扩大后新的空间一定是原来的2倍,我们可以看put()方法中有这样的一行代码:
int newCapacity = oldCapacity * 2;
所以,重点就是这个,只要一满足扩容条件,HashMap的空间将会以2倍的规律进行增大。假如我们有几十万、几百万条数据,那么HashMap要存储完这些数据将要不断的扩容,而且在此过程中也需要不断的做hash运算,这将对我们的内存空间造成很大消耗和浪费,而且HashMap获取数据是通过遍历Entry[]数组来得到对应的元素,在数据量很大时候会比较慢, 为了解决HashMap更占内存的弊端,Android提供了内存效率更高的SparseArray和ArrayMap。它内部使用两个数组进行工作,其中一个数组记录key hash过后的顺序列表,另外一个数组按key的顺序记录Key-Value值。
SparseArray
SparseArray比HashMap更省内存,在某些条件下性能更好,主要是因为它避免了对key的自动装箱(int转为Integer类型),它内部则是通过两个数组来进行数据存储的,一个存储key,另外一个存储value,为了优化性能,它内部对数据还采取了压缩的方式来表示稀疏数组的数据,从而节约内存空间,我们从源码中可以看到key和value分别是用数组表示:
private int[] mKeys; private Object[] mValues;
我们可以看到,SparseArray只能存储key为int类型的数据,同时,SparseArray在存储和读取数据时候,使用的是二分查找法,也就是在put添加数据的时候,会使用二分查找法和之前的key比较当前我们添加的元素的key的大小,然后按照从小到大的顺序排列好,所以,SparseArray存储的元素都是按元素的key值从小到大排列好的。
而在获取数据的时候,也是使用二分查找法判断元素的位置,所以,在获取数据的时候非常快,比HashMap快的多,因为HashMap获取数据是通过遍历Entry[]数组来得到对应的元素。
SparseArray应用场景:
- 数据量不大,最好在千级以内
- key必须为int类型,这中情况下的HashMap可以用SparseArray代替:
ArrayMap
当你想获取某个value的时候,ArrayMap会计算输入key转换过后的hash值,然后对hash数组使用二分查找法寻找到对应的index,然后我们可以通过这个index在另外一个数组中直接访问到需要的键值对。如果在第二个数组键值对中的key和前面输入的查询key不一致,那么就认为是发生了碰撞冲突。为了解决这个问题,我们会以该key为中心点,分别上下展开,逐个去对比查找,直到找到匹配的值。
随着数组中的对象越来越多,查找访问单个对象的花费也会跟着增长,这是在内存占用与访问时间之间做权衡交换。
ArrayMap的插入与删除的效率是不够高的,但是如果数组的列表只是在一百这个数量级上,则完全不用担心这些插入与删除的效率问题。
与HashMap相比,ArrayMap在循环遍历的时候也更加简单高效
//ArrayMap for (int i=0;i<map.size();i++){ Object keyAt=map.keyAt(i); Object valueAt=map.valueAt(i); ... } //HashMap for(Iterator it=map.keySet().iterator();it.hasNext();){ Object next = it.next(); ... };
ArrayMap应用场景:
前面讲了很多ArrayMap的优点,但并不是所有情况下都适合使用ArrayMap,我们应该在满足下面2个条件的时候才考虑使用ArrayMap:对象个数的数量级最好是千以内;
数据组织形式包含Map结构。
SparseArray和ArrayMap都差不多,使用哪个呢?
假设数据量都在千级以内的情况下: 1、如果key的类型已经确定为int类型,那么使用SparseArray,因为它避免了自动装箱的过程,如果key为long类型,它还提供了一个LongSparseArray来确保key为long类型时的使用 2、如果key类型为其它的类型,则使用ArrayMap
- SparseArray ArrayMap替代HashMap
- (HashMap,SparseArray,ArrayMap)
- SparseArray ArrayMap HashMap
- HashMap/ArrayMap/SparseArray讲解
- HashMap、ArrayMap、SparseArray分析比较
- HashMap、ArrayMap、SparseArray分析比较
- android中SparseArray和ArrayMap代替HashMap
- 使用SparseArray和ArrayMap代替HashMap
- 数据结构HashMap(Android SparseArray 和ArrayMap)
- 使用SparseArray和ArrayMap代替HashMap
- 使用SparseArray和ArrayMap代替HashMap
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- Android内存优化(使用SparseArray和ArrayMap代替HashMap)
- Unable to start adb server: error: protocol fault (couldn't read status): Connection reset by peer
- 将博客搬至CSDN
- 【R语言 可视化】R语言 ggplot2 一张图画多个饼
- 面向对象的JavaScript-1.语言特征
- 根据时间生成10位唯一性编码(最少9位)
- (HashMap,SparseArray,ArrayMap)
- Spark调优之Shuffle调优
- 【工具】Source Insight常用设置
- 城市选择插件
- python处理进制的转换
- Linux学习篇之---Ubuntu 14.04 重启后DNS配置丢失问题的解决方案,---ubuntu14.04
- A20简易Makefile解析
- 码农周刊分类整理
- BSGS及扩展BSGS