Java 集合框架中的 Deque 接口
一、介绍
双端队列,一个支持在两端插入和移除元素的线性集合。
Deque
是 “double ended queue”(双端队列)的缩写,通常发音为 “deck”。大多数 Deque
实现对其包含的元素数量没有固定限制,但该接口同时支持容量受限和没有固定大小限制的双端队列。
该接口定义了访问双端队列两端元素的方法,提供了插入、移除和检索元素的方法。每个方法都有两种形式:一种在操作失败时抛出异常,另一种则返回一个特殊值(取决于操作,返回 null
或 false
)。后一种插入操作形式专门为容量受限的双端队列设计;在大多数实现中,插入操作不会失败。
以下是 12 种双端队列方法总结:
- 操作头部元素(First Element)
操作类型 | 抛出异常 | 返回特殊值 |
---|---|---|
插入 | addFirst(e) |
offerFirst(e) |
删除 | removeFirst() |
pollFirst() |
检索 | getFirst() |
peekFirst() |
- 操作尾部元素(Last Element)
操作类型 | 抛出异常 | 返回特殊值 |
---|---|---|
插入 | addLast(e) |
offerLast(e) |
删除 | removeLast() |
pollLast() |
检索 | getLast() |
peekLast() |
此接口扩展了 Queue
接口。当双端队列用作队列时,会表现出 FIFO(先进先出)行为。元素添加到双端队列的末尾,从开头移除。继承自 Queue
接口的方法与双端队列方法完全等价,Queue
和 Deque
方法比较如下表所示:
Queue 方法 | Deque 等价方法 |
---|---|
add(e) |
addLast(e) |
offer(e) |
offerLast(e) |
remove() |
removeFirst() |
poll() |
pollFirst() |
element() |
getFirst() |
peek() |
peekFirst() |
双端队列还可以用作 LIFO(后进先出)栈。该接口应优先于传统的 Stack
类使用。当双端队列用作栈时,元素从双端队列的开头被推入或弹出。栈方法与双端队列方法等价,Stack
和 Deque
方法比较如下表所示:
Stack 方法 | Deque 等价方法 |
---|---|
push(e) |
addFirst(e) |
pop() |
removeFirst() |
peek() |
getFirst() |
需要注意的是,peek
方法在双端队列用作队列或栈时都适用;在这两种情况下,元素都来自双端队列的开头。
此接口还提供了两个用于移除内部元素的方法:removeFirstOccurrence
和 removeLastOccurrence
。
与 List
接口不同,该接口不提供基于索引的元素访问支持。
尽管双端队列的实现并不严格禁止插入 null
元素,但强烈建议不要这样做。使用允许插入 null
元素的双端队列实现的用户也被强烈建议不要利用此功能。这是因为 null
在多种方法中被用作特殊返回值,表示双端队列为空。
双端队列的实现通常不定义基于元素的 equals
和 hashCode
方法,而是继承自 Object
类的基于对象身份的版本。
二、源码
1 | public interface Deque<E> extends Queue<E>, SequencedCollection<E> { |
1、removeFirstOccurrence
boolean removeFirstOccurrence(Object o);
方法从此双端队列中移除入参元素的第一次出现。如果双端队列不包含该元素,则保持不变。
移除第一个满足 Objects.equals(o, e)
的元素(如果该元素存在)。如果此双端队列包含指定元素(或等价地说,此调用导致双端队列发生了变化),则返回 true
。
2、removeLastOccurrence
boolean removeLastOccurrence(Object o);
方法从此双端队列中移除指定元素的最后一次出现。如果双端队列不包含该元素,则保持不变。
移除最后一个满足 Objects.equals(o, e)
的元素(如果该元素存在)。如果此双端队列包含指定元素(或等价地说,此调用导致双端队列发生了变化),则返回 true
。
3、继承自 Collection 的方法
1 | boolean remove(Object o); |
3.1 remove 方法
从此双端队列中移除指定元素的第一次出现。如果双端队列不包含该元素,则保持不变。
更正式地说,移除第一个满足 Objects.equals(o, e)
的元素(如果该元素存在)。如果此双端队列包含指定元素(或等价地说,此调用导致双端队列发生了变化),则返回 true
。
此方法等同于 removeFirstOccurrence(Object)
。
3.2 contains 方法
如果此双端队列包含指定元素,则返回 true
。更正式地说,当且仅当此双端队列中至少存在一个元素 e
满足 Objects.equals(o, e)
时,返回 true
。
3.3 iterator 方法
返回一个按正确顺序遍历此双端队列中元素的迭代器。元素将按从第一个(头部)到最后一个(尾部)的顺序返回。
4、继承自 Queue 的方法
1 | boolean add(E e); |
4.1 add 方法
如果可以在不违反容量限制的情况下立即将指定元素插入此双端队列表示的队列中(换句话说,插入到此双端队列的尾部),则插入成功时返回 true
,如果当前没有可用空间,则抛出 IllegalStateException
。在使用容量受限的双端队列时,通常更倾向于使用 offer
方法。
此方法等同于 addLast
。
4.2 offer 方法
如果可以在不违反容量限制的情况下立即将指定元素插入此双端队列表示的队列中(即插入到此双端队列的尾部),则插入成功时返回 true
,如果当前没有可用空间,则返回 false
。在使用容量受限的双端队列时,此方法通常优于 add
方法,后者只能通过抛出异常来表示插入失败。
此方法等同于 offerLast
。
4.3 remove 方法
检索并移除此双端队列表示的队列的头部元素(换句话说,即此双端队列的第一个元素)。此方法与 poll()
的区别在于,当此双端队列为空时,它会抛出异常。
此方法等同于 removeFirst()
。
4.4 poll 方法
检索并移除此双端队列表示的队列的头部元素(换句话说,即此双端队列的第一个元素),如果此双端队列为空,则返回 null
。
此方法等同于 pollFirst()
。
4.5 element 方法
检索但不移除此双端队列表示的队列的头部元素(换句话说,即此双端队列的第一个元素)。此方法与 peek()
的区别在于,当双端队列为空时,它会抛出异常。
此方法等同于 getFirst()
。
4.6 peek
检索但不移除此双端队列表示的队列的头部元素(换句话说,即此双端队列的第一个元素),如果此双端队列为空,则返回 null
。
此方法等同于 peekFirst()
。
5、descendingIterator
返回一个按逆序遍历此双端队列中元素的迭代器。元素将按从最后一个(尾部)到第一个(头部)的顺序返回。
6、双端队列的 12 个方法
1 | void addFirst(E e); |
6.1 addFirst
如果可以在不违反容量限制的情况下立即将指定元素插入到此双端队列的前端,则进行插入操作;如果当前没有可用空间,则抛出 IllegalStateException
。在使用容量受限的双端队列时,通常更倾向于使用 offerFirst
方法。
6.2 addLast
如果可以在不违反容量限制的情况下立即将指定元素插入到此双端队列的末尾,则进行插入操作;如果当前没有可用空间,则抛出 IllegalStateException
。在使用容量受限的双端队列时,通常更倾向于使用 offerLast
方法。
此方法等同于 add
。
6.3 offerFirst
在不违反容量限制的情况下,将指定元素插入到此双端队列的前端。在使用容量受限的双端队列时,此方法通常优于 addFirst
方法,后者只能通过抛出异常来表示插入失败。
6.4 offerLast
在不违反容量限制的情况下,将指定元素插入到此双端队列的末尾。在使用容量受限的双端队列时,此方法通常优于 addLast
方法,后者只能通过抛出异常来表示插入失败。
6.5 removeFirst
检索并移除此双端队列的第一个元素。此方法与 pollFirst
的区别在于,当此双端队列为空时,它会抛出异常。
6.6 removeLast
检索并移除此双端队列的最后一个元素。此方法与 pollLast
的区别在于,当此双端队列为空时,它会抛出异常。
6.7 pollFirst
检索并移除此双端队列的第一个元素,如果此双端队列为空,则返回 null
。
6.8 pollLast
检索并移除此双端队列的最后一个元素,如果此双端队列为空,则返回 null
。
6.9 getFirst
检索但不移除此双端队列的第一个元素。此方法与 peekFirst
的区别在于,当此双端队列为空时,它会抛出异常。
6.10 getLast
检索但不移除此双端队列的最后一个元素。此方法与 peekLast
的区别在于,当此双端队列为空时,它会抛出异常。
6.11 peekFirst
检索但不移除此双端队列的第一个元素,如果此双端队列为空,则返回 null
。
6.12 peekLast
检索但不移除此双端队列的最后一个元素,如果此双端队列为空,则返回 null
。
相关链接
JEP 431 Sequenced Collections 顺序集合 | z2huo
OB links
[[Queue]]
[[SequencedCollection]]
[[JEP 431 Sequenced Collections 顺序集合]]
OB tags
#Java