ArrayMap
存放key-value键值对,key可以是多种类型
实现原理
存储结构,两个数组存储,一个存key的hash,一个存key和value
mHashes[],递增有序数组
mArray[],一个key对象mArray里面2个位置,保持key和value
ArrayMap优点:
- 数组缓存设计,内存利用率高,即使收缩,避免了频繁的创建数组带来的内存消耗
- 删除元素时的下界控制,防止抖动
- 迭代效率高,可以使用索引来迭代(keyAt()方法以及valueAt() 方法)
ArrayMap缺点:
- 存取复杂度高,花费大
- 二分查找的O(log n )时间复杂度远远小于HashMap
- ArrayMap没有实现Serializable,不利于在Android中借助Bundle传输。
使用场景
数量小于1000级别的,尤其是在查询多,插入数据和删除数据不频繁的情况
SimpleArrayMap
二分查找
为了解决内存抖动问题,把一些废弃的hash数组与object数组会缓存起来,下次在分配内存的时候直接使用缓存的数组
SimpleArrayMap会回收废弃的数组,在使用小于8的数组的时候,不必频繁的开辟空间
扩容:4、8、12、18
https://blog.csdn.net/industriously/article/details/72870977
SparseArray
存放key-value键值对,key只能为int
SparseBooleanArray,SparseIntArray,SparseLongArray,LongSparseArray
SparseArray<String> sparseArray= new SparseArray<>();
//增加元素,append方式
sparseArray.append(0, "myValue");
//增加元素,put方式
sparseArray.put(1, "myValue");
//删除元素,二者等同
sparseArray.remove(1);
sparseArray.delete(1);
//修改元素,put或者append相同的key值即可
sparseArray.put(1,"newValue");
sparseArray.append(1,"newValue");
//查找,遍历方式1
for(int i=0;i<sparseArray.size();i++){
Log.d(TAG,sparseArray.valueAt(i));
}
//查找,遍历方式2
for(int i=0;i<sparseArray.size();i++){
int key = sparseArray.keyAt(i);
Log.d(TAG,sparseArray.get(key));
}
实现原理
mKeys数组是按照key值递增存储的,也就是升序,
mValues数组用于存储值
SparseArray 优点:
- 避免存取元素时的装箱和拆箱
- 频繁的插入删除操作效率高(延迟删除机制保证了效率)
- 会定期通过gc函数来清理内存,内存利用率高
- 放弃hash查找,使用二分查找,更轻量
SparseArray缺点:
二分查找的时间复杂度O(log n),大数据量的情况下,效率没有HashMap高
SparseArray应用场景:
item数量为小于1000级别的,存取的value为指定类型的,比如boolean、int、long,可以避免自动装箱和拆箱问题
ArraySet
mHashes保存mArray每个元素的hash值,且mHashes和mArray相同下标的元素一一对应
优势:
ArraySet使用更少的存储单元存储元素
ArraySet使用int类型的数组存储hash,使用Object类型数组存储元素,相较于HashMap使用Node存储节点,ArraySet存储一个元素占用的内存更小。
ArraySet在扩容时容量变化更小
HashMap在扩容的时候,往往会对原来的容量扩大一倍,而ArraySet在元素超过8之后,只会增加元素个数的1/2,在扩容过程中更省内存空间。
劣势
存储大量元素(超过1000)时比较耗时
https://blog.csdn.net/hq942845204/article/details/81293480