Android中SparseArray和ArrayMap的使用
在Android项目开发中,我们经常使用HashMap存储数据。HashMap是java API中使用的,然而Android对于内存的消耗很敏感,出于性能优化,Android有时候会建议我们使用SparseArray和ArrayMap等来代替HashMap。但并不是所有的HashMap都会提示替换。那么--
1、为什么Android推荐使用SparseArray和ArrayMap?
先看HashMap的存储原理:
HashMap内部是使用一个默认容量为16的数组来存储数据的,而数组中每个元素却又是一个链表的头结点。所以,更准确的来说,HashMap内部存储结构是使用哈希表的拉链结构(数组+链表),如图所示
Entry存储的内容有key、value、hash值、和next下一个Entry。
HashMap中默认的存储大小就是一个容量为16的数组,所以当我们创建出一个HashMap对象时,即使里面没有不论什么元素。也要分别一块内存空间给它。当达到一定的容量限制时,扩容将是原来的2倍。
这样会造成两个问题,1.当数据量大的时候内存将会造成很大的浪费。2.HashMap获取数据是通过遍历Entry[]数组来得到相应的元素,在数据量非常大时候会比較慢。
再看SparseArray和ArrayMap,
SparseArray避免了HashMap的自动装拆箱的过程,因为它的key值是int类型的。它内部通过两个数组来进行数据存储的,一个int[]类型数组,用于存储key值;一个Object[]数组,用于存储value。不需要类似Entry一样的额外的结构体,单个元素的存储成本更低。
SparseArray在存储和读取数据时候,使用的是二分查找法,在数据量小的情况下,获取数据效率更高。
SparseArray插入数据时有几点需要注意:
1.存放key的数组是有序的(二分查找的前提条件)
2.如果冲突,新值直接覆盖原值,并且不会返回原值(HashMap会返回原值)
3.如果当前要插入的 key 的索引上的值为DELETE,直接覆盖
4.前几步都失败了,满容将检查是否有DELETE,若有先触发gc,再调整结构插入数据。若已满容,无法触发gc,则扩容。
SparseArray缺点是:
1.SparseArray仅仅能存储key为int类型的数据。
2.插入操作需要复制数组,增删效率降低 数据量巨大时,复制数组成本巨大,gc()成本也巨大。
3.数据量巨大时,查询效率也会明显下降。
ArrayMap和SparseArray差不多,不同的是key类型可以是其他类型。
2、SparseArray的使用
//加入数据public void put(int key, E value)//删除数据public void remove(int key)//删除数据,remove内部还是通过调用delete来删除数据的public void delete(int key)//获取数据public E get(int key)//获取数据,valueIfKeyNotFound为假设key不存在的情况下默认返回的valuepublic E get(int key, E valueIfKeyNotFound)//获取相应的keypublic int keyAt(int index) //获取相应的valuepublic E valueAt(int index)
3、ArrayMap的使用
//加入数据public V put(K key, V value) //获取数据public V get(Object key)//删除数据public V remove(Object key)//获取相应的keypublic K keyAt(int index)//获取相应的valuepublic V valueAt(int index)
更多相关文章
- Android(安卓)上SuperUser获取ROOT权限原理解析
- android 利用ksoap2方式连接webservice
- Android(二)数据存储和访问 之文件
- Android(安卓)Binder入门指南之addService详解之请求的处理
- Android连接Mysql数据库教程以及增删改查
- Android获取keystore文件的信息
- 使用AudioTrack播放PCM音频数据(android)
- Android官方架构组件ViewModel:从前世今生到追本溯源
- Android(安卓)IPC机制(四)用ContentProvider进行进程间通信