Java集合-类关系图
# 集合框架关系图
集合框架整体常见类组织关系如图(基于JDK1.8)
# 类概述
Iterable:集合实现的接口,实现该接口可以遍历该集合元素
Collection:集合框架顶层接口,定义了一些集合最基本的动作,如添加,删除,包含等。
Set:接口,继承Collection接口,一种不可以包含重复对象的集合。
List:接口,继承Collection接口,相对于Set 可以包含重复对象。
Queue:接口,继承Collection接口,是队列的顶层接口。
SortedSet:接口,继承自Set接口,在Set接口上保证了内部元素的有序性。
TreeSet:SortedSet接口的实现类,内部使用TreeMap实现,插入时会对内部元素按照自然顺序排序,或者按照指定Comparator来排序,元素都需要实现Comparable接口。
HashSet:Set接口的实现类,底层使用HashMap实现,可以保证元素的唯一性。
LinkedHashSet:Set接口的实现类,根据元素hashcode 来决定元素顺序,但是同时使用链表维护元素顺序。在迭代的时候会以元素被插入的顺序访问元素,插入开销大于HashSet,遍历开销小于HashSet
ArrayList:List接口的实现类,底层使用数组实现,内部元素可以重复
LinkedList:List接口的实现类,在底层使用链表实现,元素可以重复,迭代的时候会以元素被添加的顺序访问元素。
Vector:List接口的实现类,底层使用数组实现,线程安全。
Stack:栈,按照后进先出原则存储数据,数据操作在栈顶进行。
BlockingQueue:阻塞队列,在Queue的基础上支持两个新增动作,获取元素时等待队列非空以及存储元素的时候等待空间可用。对于新增的两个动作以4种方式出现,阻塞等待,抛出异常,返回特定值,指定时间超时。BlockingQueue 实现是线程安全的,实现通常不允许插入null元素,通常用作生产者消费者队列。
Deque:double ended queue 的缩写,表示双端队列,支持在两端插入和移除元素。没有严格要求禁止插入null元素,但是最好不要插入null元素,因为null是用来作为特殊值来指示双端队列为空
BlockingDeque:阻塞的双端队列,和BlockingQueue一样,线程安全,禁止null元素。
LinkedBlockingDeque:基于已链接节点的、任选范围的阻塞双端队列。构造器可选范围,防止过度膨胀,如果未指定容量则为
Integer.MAX_VALUE
。ArrayDeque:Deque接口的数组实现,数组实现的双端队列,没有容量限制。线程非安全,不支持多个线程并发访问,禁止null元素,次类用作堆栈比
Stack
快,在用作队列的时候比LinkedList
快。DelayQueue:无界阻塞队列,BlockingQueue的实现。内部元素必须是先
Delayed
接口,只有延迟期满才能从队列中提取元素。队列头部是延迟期满保存最久的元素,禁止null元素。(推荐查看)ArrayBlockingQueue:BlockingQueue的数组实现,有界。按照FIFO对元素进行排序,头部是队列中存在时间最长的元素。一旦创建就不可以改编队列大小,队列支持对线程的进行公平性排序的可选公平策略,默认是非公平,公平策略会降低吞吐量。
LinkedBlockingQueue:BlockingQueue的链表实现。可指定容量,按照FIFO顺序对元素进行排序,头部是在队列中时间最长的元素,吞吐量一般高于基于数组的队列。
PriorityBlockingQueue:无界阻塞队列,队列禁止null元素,线程安全,PriorityQueue阻塞版本,需要对象具有可比较性。
SynchronousQueue:无界无缓冲等待队列,isEmpty()方法一直返回true,生产者线程对其插入操作put必须等待消费者的移除操作take,反过来一样。队列头元素是第一个排队要插入数据的线程,而不是要交换的数据。数据是在配对的生产者和消费者线程之间传递的,并不会将数据缓冲到队列中。可以理解为生产者和消费者等待对方,握手然后一起离开。
PriorityQueue:基于优先级堆的无界优先级队列,实现不是同步,线程不安全。队列元素按照自然顺序排序,或者按照指定Comparator排序,禁止null元素,元素必须都要具备可比较性。
ConcurrentLinkedQueue:无界 非阻塞 线程安全队列,在多线程下的首选队列,实现比较精巧,可重点阅读源码,按照FIFO原则存储元素。
Map:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值,顶层接口。
HashTable:线程安全类 KV结构,禁止null键值。
TreeMap:SortedMap 实现类,TreeSet的内部实现类,基于红黑树实现,可以对键进行排序的Map,可用于实现一致性哈希算法。
HashMap:高效版本HashTable,线程不安全,多线程的时候,put方法容易造成循环链表导致get的时候死循环。允许null键值。
ConcurrentHashMap: 线程安全版本的HashMap,支持高并发,主要原因锁分离,减少请求锁的频率,减少持有锁的时间,读写分离,用volitile保持线程之间的可见性。
LinkedHashMap:HashMap的子类,在HashMap的基础上保留了插入顺序,在迭代的时候以插入顺序进行迭代。实现原理是在HashMap保存元素的基础上,重新定义了HashMap中的Entry,不仅保存当前对象的引用还持有有before和after两个元素的引用,从而形成了双向链表。
WeakHashMap:以弱键实现的基于哈希表的map。map中的键不再使用的时候将自动移除,更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的回收,通常我们使用短时间内就过期的缓存时最好使用weakHashMap。
# 按照使用场景分类总结
# 不允许重复元素
Set的各种实现,如TreeSet HashSet LinkedHashSet, Map的全部实现都支持key去重
# 支持自动排序
TreeSet 、TreeMap 、PriorityQueue 等
# 线程安全
老一点的集合: Stack Vector HashTable
新一点的集合:java.util.concurrent包下的所有相关类,比如ConcurrentHashMap,ConcurrentHashMap,ConcurrentHashMap ,CopyOnWriteArrayList等等,只不过他们实现线程安全的方式并不完全相同,这个后续会在源码解读中细说
# 按底层使用的数据结构区分
使用数组实现: Array 开头的各种集合,比如 ArrayList, ArrayBlockingQueue
使用链表实现:Linked开头的各种集合 比如LinkedList LinkedBlockingQueue 、
使用堆实现:PriorityQueue、DelayQueue、DelayQueue也是使用PriorityQueue实现
使用树: TreeMap TreeSet ,TreeSet底层也是使用TreeMap实现
使用哈希表实现:HashSet HashMap, HashSet底层也是使用HashMap来实现
使用栈(Stack)和队列(Queue)实现: Stack、LinkedList 和 ArrayDeque等,分别支持后进先出(LIFO)和先进先出(FIFO)
# 面试高频集合
LinkedList:如何实现存取顺序一样,如何实现LRU
HashMap:存在问题 ? 数据结构 ? 等等
ConcurrentHashMap: 如何保障线程安全 ?
CopyOnWriteArrayList:如何保障并发安全 ? 存在问题 ?
DelayQueue:什么场景使用?
LinkedBlockingQueue: 和ArrayBlockingQueue 区别? 存取细节 ?