简单梳理Android常用基本容器类原理

Android-Java:常用基本容器学习总结

1.常用容器的总体框架

在这里插入图片描述

2.常用容器类的重点

1. ArrayList

https://www.cnblogs.com/skywang12345/p/3308556.html

1.1 存储结构:
在这里插入图片描述
value值存在elementData这个Object类型的数组中,默认容量是10。
1.2 容器特点:

  1. ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。
  2. ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输.
  3. ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList.

1.3 注意事项:
5. 遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高,而使用迭代器的效率最低
6. ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList.

2. Vector

Vector 是矢量队列,继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
https://www.cnblogs.com/skywang12345/p/3308833.html
2.1 存储结构:
在这里插入图片描述
value值存在elementData这个Object类型的数组中,默认容量是10。

2.2 容器特点:

  1. Vector中的操作是线程安全的,add(),remove(),clear()等操作均加上了synchronized保护;
    在这里插入图片描述

3. Stack

Stack是继承Vector来实现,基于Vector的addElement和removeElement来实现push,pop,peek操作,因此Stack也是通过数组实现的,而非链表。
3.1 存储结构:
实质上还是用的Vector的数组实现:
在这里插入图片描述

3.2 容器特点:

  1. Stack实际上也是通过数组去实现的。
    执行push时(即,将元素推入栈中),是通过将元素追加的数组的末尾中。
    执行peek时(即,取出栈顶元素,不执行删除),是返回数组末尾的元素。
    执行pop时(即,取出栈顶元素,并将该元素从栈中删除),是取出数组末尾的元素,然后将该元素从数组中删除。
  2. Stack继承于Vector,意味着Vector拥有的属性和功能,Stack都拥有。

4. HashMap

http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/java/util/HashMap.java
4.1 存储结构:
JDK1.8 链表结构优化为数组+红黑树形式:
在这里插入图片描述

JDK1.8 之前数据+链表实现:
在这里插入图片描述
数组是HashMap的主体,链表,红黑树则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表或红黑树,那么对于查找,添加等操作很快,仅需一次寻址即可;

如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。

所以,性能考虑,HashMap中的链表出现越少,性能才会越好。

4.2 容器特点:

  1. HashMap线程不安全;
  2. HashMap可以接受为null的键值(key)和值(value)

5. HashTable

HashTable和Hashmap类似,有个HashTableEntry 类型的数组成员变量table,管理着键值对。
在这里插入图片描述
Hashtable是synchronized,这意味着Hashtable是线程安全的

但是HashTable已经被淘汰了,如果不需要线程安全,那么使用HashMap,如果需要线程安全,那么使用ConcurrentHashMap。
5.1 HashTable方法API:
在这里插入图片描述

5.2 容器特点:

  1. Hashtable 的函数都是同步的,这意味着它是线程安全的。
  2. 它的key、value都不可以为null。
  3. Hashtable中的映射不是有序的。
  4. 该类型已经提示被淘汰,需要线程安全的话可以使用ConcurrentHashMap

6. HashSet

  1. HashSet是一个集合,集合中不允许出现重复元素。
  2. HashSet是基于HashMap实现,HashSet中有一个HashMap的成员变量map,HashSet的Value 值会被以键值对<Value,PRESENT>加入到map中,由于HashMap不可以有重复的key,因而实现了set的去重。

6.1 注意事项:

  1. HashSet实现了Set接口,它不允许集合中出现重复元素。当我们提到HashSet时,第一件事就是在将对象存储在HashSet之前,要确保重写hashCode()方法和equals()方法,这样才能比较对象的值是否相等,确保集合中没有储存相同的对象。
    案例:https://www.cnblogs.com/dongying/p/4024519.html

7. ConcurrentHashMap

原理:http://www.cnblogs.com/chengxiao/p/6842045.html

7.1 存储结构:
在这里插入图片描述
Segmemt:
每个绿色方块是ConcurrentHashMap的一个Node:
在这里插入图片描述

7.2 容器特点:
1.ConcurrentHashMap是线程安全的;
1.ConcurrentHashMap不同于HashMap,它既不允许key值为null,也不允许value值为null;
2.HashTable容器的get方法是需要加锁的,而ConcurrentHashMap的get操作是不加锁的,原因是它的get方法里将要使用的共享变量都定义成volatile;
3.在ConcurrentHashMap中,每个hash区间使用的锁是ReentrantLock;

Android中独有的:

8. SparseArray

8.1 存储结构:
在这里插入图片描述
8.2 容器特点

  1. SparseArray在存储和读取数据时候,使用的是二分查找法;
  2. 满足下面两个条件我们能够使用SparseArray取代HashMap:
    a.数据量不大,最好在千级以内;
    b.key必须为int类型,这中情况下的HashMap能够用SparseArray取代;
  3. SparseArray被称为稀疏数组,原因是数组中可能并不是连续存储着value,remove方法并没有去直接删掉元素,而是将这个key指向了DELETED,这时候value失去了引用,如果没有其它的引用,会在下一次系统内存回收的时候被干掉,或者该key被复用指向新的值,是一个优化;
  4. SparseArray不需要开辟内存空间来额外存储外部映射,从而节省内存,key为int的时候才能使用,注意是int而不是Integer,这也是sparseArray效率提升的一个点,去掉了Hashmap的装箱的操作。

9. ArrayMap

https://www.jianshu.com/p/1fb660978b14
9.1数据结构:
在这里插入图片描述

  1. 数据变量含义:
    (1)mHashes,用于保存key对应的hashCode;
    (2)mArray,用于保存键值对(key,value),其结构为[key1,value1,key2,value2,key3,value3,…];
    (3)mBaseCache,缓存,如果ArrayMap的数据量从4,增加到8,用该数组保存之前使用的mHashes和mArray,这样如果数据量再变回4的时候,可以再次使用之前的数组,不需要再次申请空间,这样节省了一定的时间;
    (4)mTwiceBaseCache,与mBaseCache对应,不过触发的条件是数据量从8增长到12;
  2. allocArrays()
  3. 适用场景:
    a. 数据量不大
    b.空间比时间重要
    c.需要使用Map在Android平台,相对来说,内存容量更宝贵。而且数据量不大。所以当需要使用key是Object类型的Map时,可以考虑使用ArrayMap来替换HashMap
  4. 中占据时间复杂度最多的属于第一步:确定key的hashCode在mHahses中的索引值。而这一步对mHashes查找使用的是二分查找,即Binary Search。所以ArrayMap的查询时间复杂度为 ‎O(log n);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值