前些天花了12篇博客,分析了Java
常用的容器的源码,主要是List、Queue、Map、Set等接口的实现类。此篇博客将对这些容器进行一个总结,但不会涉及源码,如果需要了解更多的细节,可以通过文中的链接阅读。
Java常用容器JDK源码分析总结目录
一、Java容器
概述
在Java语言中,主要有四种类型的容器,分别为List
、Queue
、Map
、Set
。但是这个四个只是接口,为了方便应对不同的需求,每个接口都设计了多个实现类
。List
容器的特点是智能数组式的,可随机访问(下标访问),容量可自由伸缩;Queue
容器的特点是队头出队
、队尾入队
,一般队中间的元素不对外展示;Map
容器的特点是存放key-value
形式的数据;Set
容器的主要特点是容器中存放的元素能保持唯一性。四种接口与其实现类的继承关系图如下:
二、List
容器
1、ArrayList
容器
ArrayList
容器是通过封装一个Object
数组来实现,插入
元素前判断数组是否要扩容
,如果是插入序列中间
,还需要移动元素腾出一个空位置,删除
元素时,需要前移元素,去掉中间的空位。此容器的特点就是随机访问
(下标访问)效率高,但是移除
、插入
元素的效率低,并且不支持并发读写。
源码分析博客链接→Java容器之ArrayList源码分析(这应该是Java中最简单的容器吧)
2、Vector
容器
Vector
容器底层同样是通过数组来实现,与ArrayList
容器没啥区别。但是Vector
容器的方法都加上了synchronized
关键字,也就说Vector
容器支持并发读写,锁为this对象
,即整个容器。
源码分析博客链接→Java容器之Vector源码分析(Vector容器为啥线程安全呢?)
3、LinkedList
容器
LinkedList
容器是基于双链表
实现,但是该容器仍然实现了随机访问
(下标访问),把first
看成下标0,每次移动一个节点,下标加1,所以随机访问
的效率很低。不过由于是链表实现,所以删除
元素、插入
元素效率高,并不需要腾出空位置、扩容啥的,直接修改指针的指向即可。
源码分析博客链接→Java容器之LinkedList源码分析(LinkedList到底是单链表还是双链表?)
ArrayList
、Vector
容器都是基于数组实现,随机访问
效率高,插入、删除效率低,Vector
容器支持并发读写,引入锁机制,降低了容器的性能。LinkedList
容器基于双链表
实现,随机访问
效率低,但是插入、删除元素效率高,为引入锁机制,所以不支持并发读写。
因此如果你有大量的插入
、删除
需求,可以考虑LinkedList
容器,如果随机访问
多,则可以考虑使用ArrayList
容器,如果需要并发读写,那只能选择Vector
容器。
三、Queue
容器
1、PriorityQueue
容器
PriorityQueue
容器底层是通过数组
来维护一个堆结构
,并且这个堆结构
通过数组下标
在逻辑上成立,并没有物理实现。通过指定容器的比较器(或者将存储的类型实现comparable
接口)可构建小顶堆
(堆顶存放容器元素的最小值)、大顶堆
(堆顶存放容器元素的最大值)。
源码分析博客链接→Java容器之PriorityQueue源码分析(附堆的调整图解)
2、ArrayDeque
容器
ArrayDeque
容器是双端队列
(队头
、队尾
都支持入队
、出队
操作,普通队列只支持队头出队
,队尾入队
)容器,底层通过循环数组
实现。所谓的循环数组
,就是当下标为-1时,跳转到数组的尾端,同样当下标为数组的长度时,跳转到下标0。
源码分析博客链接→Java容器之ArrayDeque源码分析(你知道ArrayDeque维护循环数组的原理吗?)
3、LinkedList
容器
前文在List
容器中已经分析过这个容器,由于LinkedList
既实现了List
接口,又实现了Deque
接口,所以它既是List容器,又是双端队列容器。这里就不赘述了。
四、Map
容器
前面已经总结过Map
容器了,所以直接阅读前面的博客即可,链接→Java中的常见五种map容器源码分析总结(HashMap、Hashtable、ConcurrentHashMap、LinkedHashMap、TreeMap)
五、Set
容器
前面已经总结过Set
容器了,所以直接阅读前面的博客即可,链接→Java容器之HashSet、LinkedHashSet、TreeSet源码分析(不敢称东半球最好,只称东半球最好理解)
以上就是Java
常用容器JDK
源码分析总结的全部内容了。看完这些容器的源码你会发现,也就Map
容器中的TreeMap
容器、ConcurrentHashMap
容器稍微复杂一点,其它的容器的实现都比较简单。