一、容器的分类
红色虚线框:接口
绿色实线框:抽象类
黑色实线框:类
二、基本概念
Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:
- Collection,一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,而Set不能有重复元素。Queue按照队列规则来确定对象尝试的顺序(通常与它们被插入的顺序相同),双端队列是一个特例,它是队列的子接口可以在两端插入和删除数据
- Map,一组成对的“键值对”对象,允许使用键来查找值。ArrayList允许你使用数字来查找值,因此在某种意义上讲,它将数字与对象关联在了一起。映射表允许我们使用另一个对象来查找某个对象,它也被称之为“关联数组”,因为它将某些对象与另外一些对象关联在了一起,或者称之为“字典”,因为你可以使用键对象来查找值对象,就像在字典中使用单词来定义一样。Map是强大的编程工具。
三、Collection接口
Collection接口是Set,Queue,List的父接口。Collection接口中定义了多种方法可供其子类进行实现,以实现数据操作。
Collection是描述所有序列容器的共性的根接口,它可能被认为是一个附属接口,因为要表示其他若干个接口的共性而出现的接口。
3.1 相关方法
上图中是Collection中的所有方法,但是在开发过程中核心使用的方法主要有增加、删除,迭代等方法
其中重点是iterator()方法,该方法返回是迭代器,可以遍历集合中元素
3.2 迭代器
任何容器类,都必须有某种方式插入元素并将它们再次取回。毕竟,持有事物是容器最基本的工作。
迭代器的概念可以用于一个目的:面向接口编程。如果面向具体的集合编程可能由于某些原先需要替换原来的集合,那么遍历方法就需要重写,如果采用迭代器就减少了一部分的工作量。
迭代器时一个对象,它的工作时遍历并选择序列中的对象,而客户端程序员不需要只掉该序列的底层数据结构。
迭代器通常被称为轻量级对象:创建它的代价小,因此可以见到对迭代器有些奇怪的限制。
3.2.1 迭代器相关API
3.2.2 与迭代器相关的操作
- 使用方法iterator()要求容器返回一个Iterator。Iterator将准备好返回序列的第一个元素。
- 使用next()获得序列中的下一个元素。
- 使用hasNext()检查序列中是否还有元素。
- 使用remove()将迭代器新近返回的元素删除。remove元素之前必须先调用next(),因为remove移除的是新近返回的元素,如果没有调用next()就没有新近返回的元素。
3.2.3 Iterable
这个接口表示可迭代的,而且Collection接口继承了该接口。这个接口在JDK1.5中加入。
ForEach语法可以应用于实现了Iterable接口的类。
API文档
Implementing this interface allows an object to be the target of the "for-each loop" statement
实现此接口允许对象成为“for-each loop”语句的目标。
3.2.4 ListIterator
这个接口增加了一些方法,来适用于List相关的底层数据接口。
比如可以向前移动,修改等。
3.3 fail-fast机制,快速报错机制
Java容器类类库采用快速报错机制。它会探查ConcurrentModificationException异常。就是快速报错的意思。
这个机制主要是在迭代器中实现的。防止多线程在数据遍历是进行修改。
四、List
- List承诺可以将元素维护在一个特定的序列中。List接口在Collection的基础上添加了大量的方法,使得可以在List的中间插入和移除元素。
- List集合代表一个元素有序、可重复的集合,集合中每个元素都其对应的顺序索引。
- List允许使用重复的元素,可以通过索引来访问指定位置的集合元素。List默认按元素的添加顺序设置元素的索引。
- List作为Collection接口的子接口,可以使用Collection接口里的全部方法。而且由于List是有序集合,因此List集合里增加了一些根据索引来操作集合元素的方法。
4.1 相关的API
4.2 ArrayList
它长于随机访问元素,但是在List的中间插入和移动元素时较慢
具体参考:集合-ArrayList解析
4.3 LinkedList
它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序方法。LinkedList在随机访问方面相对比较慢,但是他的特性集较ArrayList更大
具体参考:集合-LinkedList解析
五、Set
5.1 相关的API
5.2 概述
存入Set的每一个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。
具体参考:集合-Set解析
六、Queue
队列是一个典型的先进先出的容器。即从容器的一段放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。队列常备当做一种可靠的将对象从程序中的某个区域传输到另一个区域的途径。队列在并发编程中特别重要
6.1 相关的API
6.2 PriorityQueue
先进先出描述最典型的队列规则。队列规则则是值在给定一组队列中的元素的情况下确定下一个优先弹出队列的元素的规则。先进先出声明的下一个元素应该是等待时间最长的元素。
优先级队列生命下一个弹出的元素时最需要的元素。
优先级队列在队列插入的时候根据Compartor(Comparable)进行排序。
具体参考队列
6.3 Dueue,双端队列
支持两端元素插入和移除的线性集合。
LinkedList实现了双端队列的API
6.4 ArrayDeque
默认长度是16的循环数组。
使用head和tail两个int类型的字段来记录数组的开始和结尾。
如果head和tail相等,那么就进行数据扩容,扩容是将数据copy到扩容后的数组,并且新数组中的数据是从0位置开始的。
七、Map
将对象映射到其他对象的能力是一种解决编程问题的杀手锏。
7.1 Map相关的API
7.2 具体实现及说明
实现 | 说明 |
---|---|
HashMap* | Map基于散列表的实现(它取代了Hashtable)。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量和负载因子,以调整容器的性能。 |
LinkedHashMap | 类似于HashMap,但是迭代遍历它是,取的“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点;而在迭代访问时反而更快,因为它使用链表维护内部次序 |
TreeMap | 基于红黑树的实现。查看“键”或“键值对”是,他们会被排序(次序由Comparable或Comparator决定)。TreeMap的特点在于,所得到结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树 |
WeakHashMap | 弱键(weak key)映射,允许释放映射所指向的对象,这是为解决某类特殊问题而设计的。如果映射之外没有引用指向某个“键”,则此“键”可以被垃圾收集器回收 |
ConcurrentHashMap | 一种线程安全的Map,它不涉及同步加锁。 |
IndentityHahsMap | 使用==代替equals()对“键”进行比较的散列映射,专为解决特殊问题设计的。 |
八、工具类
8.1 Collections
处理集合相关的工具类
8.2 Arrays
处理数组的工具类
该类包含用于操作数组的各种方法(如排序和搜索)。 该类还包含一个静态工厂,可以将数组视为列表。
参考
- 中文API文档,该链接中有多个翻译版本的API文档
- Google翻译的文档
- 官方文档
- 集合框架
其他文章
容器解析
ArrayList解析
LinkedList解析
TreeMap解析(上)
TreeMap解析(下)
HashMap解析
LinkedHasMap解析(下)
Set解析