环境和版本
- Mac M1
- IDEA 2021
- Zulu Open JDK
简介:集合框架,将会是一个非常好玩的地方,可以任意分析各种源码的实现。里面会用到很多的概率论知识、
高等数学知识等。
目标:精通各种集合框架的底层实现,可以手写各种集合框架。
下一个阶段的目标:现在只是讲解Java集合框架基础的部分,也就是常用的,但是还有一些和多线程相关的集合框架,需要在JUC的时候进行单独学习。
整体继承体系概览
- 顶级接口是啥、一个集合从哪些接口实现的
- 来个更详细的
容器:容纳其他对象的对象
ArrayList
- ArrayList 是由数组实现的,支持随机存取,也就是可以通过下标直接存取元素;
- 从尾部插入和删除元素会比较快捷,从中间插入和删除元素会比较低效,因为涉及到数组元素的复制和移动;
如果内部数组的容易不足时会自动扩容,因此当元素非常庞大的时候,效率会比较低。
LinkedList
LinkedList 是由双向链表实现的,不支持随机存取,只能从一端开始遍历,直到找到需要的元素后返回;
- 任意位置插入和删除元素都很方便,因为只需要改变前一个节点和后一个节点的引用即可,不像 ArrayList 那样需要复制和移动数组元素;
因为每个元素都存储了前一个和后一个节点的引用,所以相对来说,占用的内存空间会比 ArrayList 多一些。
Vector 和 Stack
List 的实现类还有一个 Vector,是一个元老级的类,比 ArrayList 出现得更早。ArrayList 和 Vector 非常相似,只不过 Vector 是线程安全的,像 get、set、add 这些方法都加了 synchronized 关键字,就导致执行执行效率会比较低,所以现在已经很少用了。
- 更好的选择是并发包下的 CopyOnWriteArrayList。
- Stack 是 Vector 的一个子类,本质上也是由动态数组实现的,只不过还实现了先进后出的功能(在 get、set、add 方法的基础上追加了 pop、peek 等方法),所以叫栈。
- 不过,由于 Stack 执行效率比较低(方法上同样加了 synchronized 关键字),就被双端队列 ArrayDeque 取代了。
Set
Set 的特点是存取无序,不可以存放重复的元素,不可以用下标对元素进行操作,和 List 有很多不同
HashSet
HashSet 其实是由 HashMap 实现的,只不过值由一个固定的 Object 对象填充,而键用于操作。
LinkedHashSet
-
TreeSet
TreeSet 是由 TreeMap 实现的,只不过同样操作的键位
SortedSet
-
Queue
Queue,也就是队列,通常遵循先进先出(FIFO)的原则,新元素插入到队列的尾部,访问元素返回队列的头部。
ArrayDeque
- ArrayDeque 是一个基于数组实现的双端队列,为了满足可以同时在数组两端插入或删除元素的需求,数组必须是循环的,也就是说数组的任何一点都可以被看作是起点或者终点。
- 这是一个包含了 4 个元素的双端队列,和一个包含了 5 个元素的双端队列。
head 指向队首的第一个有效的元素,tail 指向队尾第一个可以插入元素的空位,因为是循环数组,所以 head 不一定从是从 0 开始,tail 也不一定总是比 head 大。
LinkedList
LinkedList 一般都归在 List 下,只不过,它也实现了 Deque 接口,可以作为队列来使用。等于说,LinkedList 同时实现了 Stack、Queue、PriorityQueue 的所有功能。
PriorityQueue
PriorityQueue 是一种优先级队列,它的出队顺序与元素的优先级有关,执行 remove 或者 poll 方法,返回的总是优先级最高的元素。
- 要想有优先级,元素就需要实现 Comparable 接口或者 Comparator 接口。
Map
Map 保存的是键值对,键要求保持唯一性,值可以重复。
HashMap
HashMap 实现了 Map 接口,根据键的 HashCode 值来存储数据,具有很快的访问速度,最多允许一个 null 键。
LinkedHashMap
大多数情况下,只要不涉及到线程安全的问题,有需要键值对的时候就会使用 HashMap,但 HashMap 有一个问题,就是 HashMap 是无序的。在某些场景下,我们需要一个有序的 Map。
- 于是 LinkedHashMap 就闪亮登场了。LinkedHashMap 是 HashMap 的子类,内部使用链表来记录插入/访问元素的顺序。
LinkedHashMap 可以看作是 HashMap + LinkedList 的合体,它使用了 哈希表来存储数据,又用了双向链表来维持顺序。
TreeMap
HashMap 是无序的,所以遍历的时候元素的顺序也是不可测的。TreeMap 是有序的,它在内部会对键进行排序,所以遍历的时候就可以得到预期的顺序。
- 为了保证顺序,TreeMap 的键必须要实现 Comparable 接口或者 Comparator 接口。
集合框架总结
TODO