1. Java 集合框架体系图
2. Java 中容器总结
Collection
: 根接口,表示单个元素的集合,有基本的增、删、查、遍历等方法,但没有定义元素间的顺序或位置,也没有规定是否有重复元素List
: 是Collection
的子接口,表示有位置或顺序的数据集合,增加了根据索引位置进行操作的方法ArrayList
: 基于数组实现,随机访问效率很高,但从中间插入和删除元素需要移动元素,效率比较低LinkedList
: 基于链表实现,与ArrayList
特点相反,随机访问效率比较低,但增删元素只需要调整临近节点的链接,效率比较高
Set
: 是Collection
的子接口,没有增加新的方法,但保证不含重复元素HashSet
: 基于哈希表实现,要求键重写hashCode()
方法,效率很高,但元素间没有顺序LinkedHashSet
: 可以按插入有序
TreeSet
: 基于排序二叉树实现,元素按键比较有序,元素需要实现Comparable
接口,或者创建TreeSet
时提供一个Comparator
对象EnumSet
: 针对枚举类型,基于位向量实现,效率很高
Queue
: 是Collection
的子接口,表示先进先出的队列,在尾部添加,在头部查看或删除Deque
: 是Queue
的子接口,表示更为通用的双端队列,有明确的在头或尾进行查看、添加和删除的方法。ArrayDeque
: 普通队列的实现类,基于循环数组实现- 普通队列有两个主要的实现类:
LinkedList
和ArrayDeque
。LinkedList
基于链表实现,ArrayDeque
基于循环数组实现。一般而言,如果只需要Deque
接口,ArrayDeque
的效率更高一些
PriorityQueue
: 是一个特殊的Queue
的实现类,表示优先级队列,内部是用堆实现的。堆除了可以用于实现优先级队列,还可以高效方便地解决很多其他问题,比如,求前 K 个最大的元素、求中值等
Map
: 根接口,表示键值对的集合,经常根据键进行操作HashMap
: 基于哈希表实现,要求键重写hashCode()
方法,操作效率很高,但元素没有顺序LinkedHashMap
: 按插入或访问有序。之所以能有序,是因为每个元素还加入到了一个双向链表中。如果键本来就是有序的,使用LinkedHashMap
而非Treemap
可以提高效率。按访问有序的特点是可以方便地用于实现 LRU 缓存
TreeMap
: 基于红黑树(大致平衡的排序二叉树)实现,要求键实现Comparable
接口,或提供一个Comparator
对象,操作效率稍低,但可以按键有序EnumMap
: 是Map
的一个专门的实现类,键为枚举类型,内部使用效率更高的两个数组实现
3. Java 中容器类的线程安全性
- 除了
Hashtable
、Vector
和Stack
,其他容器类都是线程不安全的。即:如果多个线程同时读写同一个容器对象,是不安全的 - 如果需要线程安全,可以使用
Collections
提供的synchronizedXXX()
方法对容器对象进行同步,或者使用专门的线程安全的容器类
4. 容器类中的迭代器的特点是
- 都会在迭代过程中进行结构性变化检测,如果容器发生了结构性变化,就会抛出
ConcurrentModificationException
异常 - 所以不能在迭代中直接调用容器类提供的
add()/remove()
方法。如需添加和删除,应调用迭代器的相关方法