1、概述
集合是Android开发比较重要的知识点,数据集合是同来存储数据的容器,通过容器给提供的接口可对容器中的数据进行增删查改。为了满足开发者的不同需要,JDK提供多种类型的集合,这里我们整理了一下Java 提供的集合类,便于以后的记忆。
把众多的集合类划分为两大类。
- 即非键值对的存储集合
- 在存储数据时提供一个Key,即以Key-Value键值对的方式存储
两种类型的集合分别实现下面两个接口。
- Collection:定义一个数据容器的接口
- Map
2、Collection
Collection中定义的接口如下:
为了满足不同的开发需求,Collection派生出多种存储方式的集合类
从Collection直接派生出三个重要的接口:
1. List:每一个元素都会有一个唯一索引
2. Queue:提供先进先出(FIFO)的存储特点,即队列的存储结构
3. Set:存储的元素是无序且不能重复
AbstractCollection:实现了Collection的通用接口,并从AbstractCollection派生出三个重要的抽象类:
1. AbstractList:实现了List通用的操作
2. AbstractQueue:实现了Queue 中重用的操作
3. AbstractSet:实现了Set 中重用的操作
List
存储在List中的元素是有序的,每个元素对于一个index,我们可通过一个index取出对应的元素,即存储的数据是有序的。
- AbstractList: 该抽象类实现了有序集合通用的操作。
- Vector:该集合内部使用一个数组来存储数据,该集合的操作是线程安全的,但该通过迭代器来遍历该集合时,开销会比较大,因为使用迭代器来遍历元素时会使用到get()方法,而这个方法是进行锁操作的,所以这点需要注意。
- Stack:继承Vector,支持后进先出的数据存储结构,这属于数据结构中的栈
- ArrayList:该集合类的实现和Vector集合类基本一样,内部都是通过数组来实现,不同的是Vector集合的操作是线程安全的,如果我们并不需要那么多的同步操作,那ArrayList就是我们的最好选择。
- CopyOnWriteArrayList:提供同步机制的List集合,如果你需要比较高的并发访问,那推荐使用CopyOnWriteArrayList
- LinkedList:该集合使用一个双向链表来存储数据,提供了有序的存储结构。所以该集合非常适用于实现队列,即提供先进先出的存储机制。
Queue
Queue提供先进先出的存储机制,以下是Queue集合树
- AbstractQueue:实现了Queue通用的接口,把Queue集合能抽象的操作都在AbstractQueue中实现。
- BlockingQueue:提供阻塞等待的机制,往集合中添加一个元素时,如果没有可用的空间,那添加操作就会被阻塞,直到有可用的空间才把元素添加到集合中,BlockingQueu有很多实现类,我们可根据自己需求选择不同实现类。
- Deque:提供双端队列的存储机制,可从队列头部添加数据,也可从队列头图取出数据。
- ConcurrentLinkedQueue:一个没容量限制的线程安全集合类,该集合类的内部是通过一个链表来存储数据。
- LinkedList:内部是使用链表结构来存储数据,所以对于List集合的特性和Queue集合特性,LinkedList集合都能很方便的实现,所以该集合即是List集合也是Queue集合。
Set
Set集合存储的元素是不能有重复的,且是没有顺序,Set代表数学领域的集合。
- HashSet: 内部使用HashMap来实现
- SortedSet:对元素的遍历时有序的,元素的排序机制有构造函数中传递进来的 Compartor对象决定 或者是元素的equal方法。
- NavigableSet:提供相近的数据存取接口
- TreeSet:内部使用TreeMap来实现
- LinkedHashSet:内部使用LinkedHashMap实现。
提示:Set集合的具体实现类很多都是通过相应的Map来作为数据存储
3、Map
这是以键值对存储的集合,通过一个键可以查找到相应的值。Map继承结构如下:
1. AbstractMap: Map集合的通用实现的抽象类,需要注意的是该抽象类中的接口实现效率都是很低。
2. HashTable:和HashMap的存储结构一样,只是HashTable的操作都是同步的,所以效率会比HashMap低
3. WeakHashTable:该结构和HashTable一样,该集合的Key值是弱引用的,当Key对象被回收时,集合中会移除相应的Key-Value
4. SortedMap:集合中的键值对是有序的,排序的依据是Key值的equal()方法的比较结构,或者是创建集合传递进去的Compartor对象
5. NavigableMap:提供相近的数据存取接口
重点来讲解一下HashMap,HashMap的存储结构如下图所示:
给Hash添加一个键值对的流程如下:
* 创建HashMap对象时,会默认创建一个长度的16的Entry数组
* 当我们调用put(K, V)方法添加一个键值对时,首先取出Key的hashCode
* 根据Key的HashCode,对数组长度取模,得到数组的下标index
* 使用K和V创建一个新的NewEntry
* 根据下标index拿到数组的元素Entry,如果Entry为NULL,那把NewEntry添加到数组元素中
* 如果Entry不为NULL,则遍历以Entry为链表头的链表,看是否有Entry的Key和NewEntry的Key是equal的
* 有的话更新旧的Entry
* 没有的话,则把NewEntry插入到链表头