Deque用法及原理讲解
Deque用的比较少,但是还是一个功能十分强大的队列,这种双向队列即可以支持先进后出,也能支持先进先出的格式,相当于同时实现了Stack和Vector,
从上图看出,Queue以及Deque都是继承于Collection,Deque是Queue的子接口。
从Deque的解释中,我们可以得知:Deque是double ended queue,我将其理解成双端结束的队列,双端队列,可以在首尾插入或删除元素。而Queue的解释中,Queue就是简单的FIFO队列。所以在概念上来说,Queue是FIFO的单端队列,Deque是双端队列。
LinkedList以及ArrayDeque
从官方解释来看,ArrayDeque是无初始容量的双端队列,LinkedList则是双向链表。而我们还能看到,ArrayDeque作为队列时的效率比LinkedList要高,而在栈的使用场景下,无疑具有尾结点不需判空的LinkedList较高效。
下面演示ArrayDeque作为队列以及LinkedList作为栈的使用:
private static void usingAsQueue() {
Deque<Integer> queue=new ArrayDeque<>();
System.out.println("队列为空:"+queue.isEmpty()); //判断队列是否为空
queue.addLast(12); //添加元素
System.out.println("队列为空:"+queue.isEmpty()); //判断队列是否为空
System.out.println(queue.peekFirst()); //获取队列首部元素
System.out.println(queue.pollFirst()); //获取并移除栈顶元素
System.out.println("队列为空:"+queue.isEmpty()); //判断队列是否为空
}
private static void usingAsStack() {
//作为栈使用
Deque<Integer> stack=new LinkedList<>();
System.out.println("栈为空:"+stack.isEmpty()); //判断栈是否为空
stack.addFirst(12);
System.out.println("栈为空:"+stack.isEmpty()); //判断栈是否为空
System.out.println(stack.peekFirst()); //获取栈顶元素
System.out.println(stack.pollFirst()); //获取并移除栈顶元素
System.out.println("栈为空:"+stack.isEmpty()); //判断栈是否为空
System.out.println("============================================");
}
小提示
在Deque中,获取并移除元素的方法有两个,分别是removeXxx以及peekXxx。
存在元素时,两者的处理都是一样的。但是当Deque内为空时,removeXxx会直接抛出NoSuchElementException,而peekXxx则会返回null。
所以无论在实际开发或者算法时,推荐使用peekXxx方法
其实ArrayDeque和LinkedList都可以作为栈以及队列使用,但是从执行效率来说,ArrayDeque作为队列以及LinkedList作为栈使用会是更好的选择。