Java的 LinkedList 是一种重要的集合,它既可以实现单向和双向队列,也可以作为堆来使用。
如果在 API 中查看 LinkedList 的方法,会发现有很多方法功能十分相似,根本分不清来自于哪个数据结构。
下面,本文将对 LinkedList 中实现的两个重要的接口:Queue 和 Deque进行梳理。
Queue
Queue<Integer> m_queue = new LinkedList<>();
Queue接口窄化了对 LinkedList 中方法的访问权限,为实现先进先出的队列规定了特定的方法。
同时,不论是Queue 还是 Deque,
每一种操作对应的方法都以两种形式存在:一种在操作失败时抛出异常,另一种返回特殊值( null或false ,具体取决于操作)
。
因此常用方法如下:
抛出异常 | 返回特殊值 |
---|---|
add(e) | offer(e) |
remove() | poll() |
element() | peek() |
Queue在使用时更推荐返回特殊值的一组函数,以避免方法失败时直接抛出异常。
Deque
Deque<Integer> m_deque = new LinkedList<>();
Deque 继承了 Queue 接口,它主要由三种用途:双端队列、栈、普通队列。
1.双端队列
双端队列的相关方法如下:
可以发现,无论是普通队列还是双端队列,抛出异常的一组都是add、remove、get系列的;返回特殊值的一组则是offer、poll、peek系列的。
如果没有特殊需求,都是推荐使用返回特殊值的一组。
还有一点需要注意,Deque作为双端队列时也可以调用 element() 和 peek() 方法,二者在双端队列中等同于 getFirst() 和 peekFirst()。
2.栈
Java 中堆栈类 Stack 已经过时,官方推荐使用Deque来实现堆栈。
Deque 作为堆栈只需要记住三个方法就可以了:
push(e)、pop()、peek()。
3.普通队列
由于 Deque 继承了 Queue,因此用Deque实现普通队列,使用上面 Queue 的方法也是完全可以的,也可以使用双端队列中“先进”和“先出”的方法。不过个人建议如果只是想实现普通队列,就直接用 Queue,更简洁明了,也方便记忆。