Java Collections Framework中大的接口分两部分:一部分是Collection接口及其子接口,另一部分是Map接口及其子接口。这里先主要记一下Collection接口相关的层次结构以及各个接口介绍。
Interface Iterable
Collection接口是框架的一部分,但是却不是最顶层接口,最顶层的接口是Iterable,但Iterable却不算是框架部分。实现Iterable接口的类需要能成为for-each loop的目标。大概意思就是能做for循环。在jdk1.8之前,实现这个接口需要实现的方法只有一个 Iterator
,该方法返回一个迭代器,1.8之后多了两个方法default void forEach(Consumer super T> action)
和default Spliterator
,forEach方法传入一个action动作,处理每个对象;而spliterator方法则是返回一个分割的迭代器,使迭代更加快速。
Interface Collection
该接口是Collection结构中的根接口。Collection表示一组对象,每个对象称为其元素。有些Collection允许重复元素,有些不允许;有些是有序的,有些是无序的。JDK中没有这个接口的直接实现类,但是该接口有许多Set或者List的子接口。所有的Collection实现类(通常是通过实现其子接口的类),都实现两个标准构造方法,一个是无参的构造方法,另一个是单个参数Collection的构造方法。后一个构造方法允许复制任何一个Collection生成一个指定类型的Collection。接口中不能规定构造函数,所以不能强制实现类都遵守这个约定,但是java库里的实现类都遵从。
Interface List
一个有序的Collection,也叫序列。这个接口能够精确控制插入其中的每个元素,这个接口能够通过索引查询,访问其中任意元素。这与Sets不同,这里允许元素重复,如果允许插入null元素,也可以插入多个null元素。对于一些如LinkedList
实现,通常迭代器比索引更好。该接口返回ListIterator,该迭代器除了有Iterator的方法,还允许插入,替换元素,允许双向访问。这里还提供一个从指定位置返回迭代器方法。List提供两种方法搜索对象,但是要谨慎使用,在一些实现中,会执行耗性能的线性搜索。常用的ArrayList
就是实现了这个接口
Interface Queue
翻译为队列,这里定义的方法总共有6个方法。并且只实现这个接口的类只有一个抽象类,其余的类实现该接口的同时还实现了其它接口。
抛出异常 | 返回特殊值 | |
---|---|---|
插入 | add(e) |
offer(e) |
移除 | remove() |
poll() |
检查 | element() |
peek() |
6个方法分两类,抛出异常的一种和不抛异常返回特殊值的。移除相关的方法返回队列第一个元素,并且从队列中删除该元素,而检查相关的方法则获取第一个元素,但是不会从队列中移除。通常应该避免在队列添加空元素(尽管某些队列可以添加null元素),这是因为由于poll方法在队列没有元素时,不抛出异常,而是返回null。
Interface BlockingQueue
该接口继承自Queue接口。这个接口比父接口多了两个操作,获取元素时可以等待元素变的可用再获取,插入元素等待队列空间变的可用再插入。
抛出异常 | 特殊值 | 阻塞 | 超时 | |
---|---|---|---|---|
插入 | add(e) |
offer(e) |
put(e) |
offer(e, time, unit) |
移除 | remove() |
poll() |
take() |
poll(time, unit) |
检查 | element() |
peek() |
不可用 | 不可用 |
相比父接口,多了阻塞和超时两个种类。阻塞:插入时,如果空间不可用,当前线程会一直等待直到有空间存储。移除时,如果当前队列为空当前线程会一直等待,直到队列有可用元素移除。超时:与阻塞类似,不过可以指定等待的时间,如果超过指定时间仍不可用,仍会向下执行。
BlockingQueue接口不支持空元素,添加null会抛出空指针异常。因为null是poll方法操作失败的警戒值。
该接口是线程安全的,利用该接口的类可以实现消息队列,多生产者-多消费者模式,而不需要自己去处理相关线程安全的问题。
Interface TransferQueue
自JDK1.7之后新增的一个接口。属于Collections框架的一部分。继承自BlockingQueue
接口,它是一种生产者能够等待消费者接收元素的BlockingQueue。TransferQueue在一些消息传递的应用中非常有用,生产者可以使用transfer(E)
等待消费者调用take
或者poll
来接收元素,也可以使用put
而不需要等待去接收,同时还有无阻塞和超时两种版本的tryTransfer
方法。同时hasWaitingConsumer()
方法可以查询队列是否有线程正在等待接收。
与其它队列一样,TransferQueue
也可能有容量限制,如果是这样,可能队列在一开始的transfer操作就可能会因为等待空间而阻塞,之后可能会为等待消费者接收而阻塞。如果队列的容量为0,就像SynchronousQueue
,put和transfer效果是一样的。
Interface Deque
double ended queue(双端队列),大多数没有容量限制。但是接口既支持有容量的,也支持没有容量限制的。deque与queue接口类似,不过可以在两端操作。方法操作失败结果有两种,一种是会抛出异常,另一种会返回特殊值(null或者false)。
第一个元素(头部) | 最后一个元素(尾部) | |||
---|---|---|---|---|
抛出异常 | 特殊值 | 抛出异常 | 特殊值 | |
插入 | addFirst(e) |
offerFirst(e) |
addLast(e) |
offerLast(e) |
移除 | removeFirst() |
pollFirst() |
removeLast() |
pollLast() |
检查 | getFirst() |
peekFirst() |
getLast() |
peekLast() |
与queue接口中等效的方法
Queue方法 | 等效 Deque 方法 |
---|---|
add(e) |
addLast(e) |
offer(e) |
offerLast(e) |
remove() |
removeFirst() |
poll() |
pollFirst() |
element() |
getFirst() |
peek() |
peekFirst() |
与堆栈等效的方法
堆栈方法 | 等效 Deque方法 |
---|---|
push(e) |
addFirst(e) |
pop() |
removeFirst() |
peek() |
peekFirst() |
不支持通过索引访问元素。
Interface BlockingDeque
继承了两个接口:Deque和BlockingQueue。与BlockingQueue继承Queue差不多,BlockingDeque是Deque的线程安全版本。提供队列可用的等待方法。
第一个元素(头部)
抛出异常 | 特殊值 | 阻塞 | 超时期 | |
---|---|---|---|---|
插入 | addFirst(e) |
offerFirst(e) |
putFirst(e) |
offerFirst(e, time, unit) |
移除 | removeFirst() |
pollFirst() |
takeFirst() |
pollFirst(time, unit) |
检查 | getFirst() |
peekFirst() |
不适用 | 不适用 |
最后一个元素(尾部)
抛出异常 | 特殊值 | 阻塞 | 超时期 | |
---|---|---|---|---|
插入 | addLast(e) |
offerLast(e) |
putLast(e) |
offerLast(e, time, unit) |
移除 | removeLast() |
pollLast() |
takeLast() |
pollLast(time, unit) |
检查 | getLast() |
peekLast() |
不适用 | 不适用 |
BlockingDeque可以直接用作FIFO的BlockingQueue,等效方法如下
BlockingQueue方法 | 等效的 BlockingDeque 方法 |
---|---|
插入 | |
add(e) |
addLast(e) |
offer(e) |
offerLast(e) |
put(e) |
putLast(e) |
offer(e, time, unit) |
offerLast(e, time, unit) |
移除 | |
remove() |
removeFirst() |
poll() |
pollFirst() |
take() |
takeFirst() |
poll(time, unit) |
pollFirst(time, unit) |
检查 | |
element() |
getFirst() |
peek() |
peekFirst() |
Interface Set
与数学上集合概念一致,不包括重复元素,里边方法大致与Collection接口中继承的方法一致。
- 这里需要注意的是将一个可变对象用作集合的元素,这里说的可变元素是指会改变equals比较的值。
- 禁止向集合中添加自身。
- 避免添加null元素。
Interface SortedSet
继承自Set接口,顾名思义,排序的集合,其中的所有元素默认按自然顺序由小到大排序。
添加到其中的所有元素需要实现Comparable
接口。注意compareTo
与equals
方法的一致性。
多出来的一些方法如下
方法 | 描述 |
---|---|
E first() |
返回集合中第一个元素 |
SortedSet headSet(E toElement) |
返回当前集合的子集合,其元素小于toElement |
E last() |
返回集合中的最后一个元素 |
default Spliterator |
创建一个当前有序集合的Spliterator |
SortedSet |
返回包括fromElement 不包括toElement 的子集合 |
SortedSet |
子集合大于fromElement |
Interface NavigableSet
扩展的SortedSet
接口,多出的一些方法如下
方法 | 描述 |
---|---|
E ceiling(E e) |
返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null |
Iterator descendingIterator() |
以降序返回在此 set 的元素上迭代器 |
NavigableSet descendingSet() |
返回此 set 逆序集合。 |
E floor(E e) |
返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null 。 |
NavigableSet headSet(E toElement, boolean inclusive) |
返回此 set 的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement 。 |
E higher(E e) |
返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null 。 |
E lower(E e) |
返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null 。 |
E pollFirst() |
获取并移除第一个(最低)元素;如果此 set 为空,则返回 null 。 |
E pollLast() |
获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null 。 |
NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) |
元素范围从 fromElement 到 toElement 。 |
NavigableSet tailSet(E fromElement, boolean inclusive) |
元素大于(或等于,如果 inclusive 为 true)fromElement 。 |