Deque介绍
在Java中,有两种非常常用的数据结构,分别是队列和栈,而该接口的实现类可以同时实现上述的两种数据结构,该接口就是Deque,Deque接口全称Double Ended Queue,名为双端队列,是一种既可以实现栈,也可以实现队列的数据结构,Deque接口继承了Queue接口的方法,对于插入元素、删除元素、元素检查等操作遇到处理失败时都存在两套不同的处理方案,具体差别如下:
首个元素(Head) | 尾端元素(Tail) | |||
---|---|---|---|---|
操作 | 抛出异常 | 返回特定值 | 抛出异常 | 返回特定值 |
插入 | addFirst(e) | offerFirst(e) | addLast(e) | offerLast(e) |
移除 | removeFirst() | pollFirst() | removeLast() | pollLast() |
检查 | getFirst() | peekFirst() | getLast() | peekLast() |
作为队列使用
当将Deque的实现类作为一个队列来使用时(FIFO:First-In-First-Out),队列中的元素将从尾部添加,头部删除,Deque接口和Queue接口中的方法对应关系如下所示:
Queue方法 | 对等的 | Deque方法 | 方法说明 |
---|---|---|---|
add(e) | addLast(e) | 如果没有达到存储容量限制则立刻从尾部插入元素,插入失败则抛出异常;如果是容量受限的双端队列,更适合的是 offerLast 方法 | |
offer(e) | offerLast(e) | 如果没有到达容量上限则从尾部插入元素并返回true,如果已经达到容量上限则插入失败并返回false;如果是其它异常则抛出异常 | |
remove() | removeFirst() | 取出并移除该Deque中的第一个元素,该方法和pollFirst的最大区别就是当Deque为空时该方法会抛出NoSuchElementException异常 | |
poll() | pollFirst() | 取出并移除该Deque中的第一个元素,如果为空则返回null | |
element() | getFirst() | 取出但不移除当前Deque的第一个元素,该方法与peekFirst的最大区别就是当Deque为空的时候,该方法会抛出NoSuchElementException异常 | |
peek() | peekFirst() | 取出但不移除当前Deque的第一个元素,当Deque为空时,返回null |
作为栈使用
Deque也可以作为栈来使用(LIFO:Last-In-First-Out),该接口作为栈使用性能优于Stack类,当Deque作为一个栈来使用的时候,栈中的元素入栈和出栈都从Deque的头部来进行操作,下面是Stack类中的方法和Deque接口中的方法的对应关系:
Stack方法 | 对等的 | Deque方法 | 方法说明 |
---|---|---|---|
push(e) | addFirst(e) | 如果没有达到存储容量限制则立刻从头部插入元素,插入失败则抛出异常;如果是容量受限的双端队列,更适合的是 offerFirst 方法 | |
pop() | removeFirst() | 取出并移除该Deque中的第一个元素,该方法和pollFirst的最大区别就是当Deque为空时该方法会抛出NoSuchElementException异常 | |
peek() | peekFirst() | 取出但不移除当前Deque的第一个元素,当Deque为空时,返回null |
注意事项
-
与List接口不同,Deque接口没有提供基于下标来查找元素的方法
-
Deque的具体实现类中没有强制禁止插入为null的元素,但是强烈不介意这样做,因为null在某些方法中是作为一种特殊的返回值来处理的,如果存入null元素,在调用这些方法的时候会有歧义产生
其它方法说明
作为(Collection)集合的方法
remove(o)
移除该双端队列中的首次出现的与该参数相等的元素并返回true,如果不存在则返回false,如果不存在则该双端队列未发生变化,该方法等同于 removeFirstOccurrence(Object) 方法
contains(o)
如果当前Deque中存在至少一个该元素则返回true,如果不存在则返回false, 其它情况则抛出异常信息
size()
返回当前Deque的元素的个数
针对于栈的方法
pop()
出栈一个元素,换句话说就是移除并返回Deque中的第一个元素,如果为空则抛出NoSuchElementException异常;该方法等同于removeFirst;
push(e)
入栈一个元素,换句话说就是将当前元素作为头节点,如果超过了存储容量限制,则抛出异常;该方法等同于addFirst;
针对于队列的方法
add(e)
将当前的Deque作为一个队列来使用,从队列的尾部来进行添加,添加成功则返回true,如果添加失败则抛出异常,针对于有存储容量限制的队列,更适合的方法是offer
offer(e)
将当前的Deque作为一个队列来使用,从队列的尾部来进行添加,如果添加成功则返回true,如果由于容量限制导致的添加失败则返回false,特定情况会抛出异常
remove()
从头部取出并移除当前Deque中的头部元素,该方法与poll的不同就在于当Deque为空的时候该方法会抛出NoSuchElementException异常,该方法等同于 removeFirst()方法
poll()
取出并移除当前队列的头部元素,如果队列为空则返回null,该方法等同于pollFirst()方法
element()
取出但不移除该队列的头部元素,该方法与 peek 方法的区别就是当队列为空时该方法会抛出 NoSuchElementException 异常,该方法等同于 getFirst()方法
peek()
取出但不移除该队列的头部元素,如果队列为空则返回null,该方法等同于peekFirst()方法
总结
通过上面的分析,我们知道了Deque接口常用的方法和特点,接下来的文章,我们会对Deque对应的一些实现类进行具体的分析,深入了解他们的存储原理和特点,为我们日常的开发提供充足的知识储备
常用实现类
* ArrayDeque: ArrayDeque详解-Deque接口数组实现方案-CSDN博客
* ConcurrentLinkedDeque: ConcurrentLinkedDeque详解-Deque接口链表实现方案-CSDN博客
* LinkedList:LinkedList详解-Deque接口链表实现方案-CSDN博客