1. 简介
Java中的数据结构队列(Queue)是一种线性表,其特殊之处在于它只允许在表的后端进行插入操作,在表的前端进行删除操作。这种先进先出(FIFO,First In First Out)的结构类似于现实生活中的排队,最早等待的人将最先得到服务。
2. 特点
队列的特点特别简单,先进先出。
2.1 分类
- 单向队列(Queue):只能在一端插入数据,在另一端删除数据。
- 双向队列(Deque):每一端都可以进行插入数据和删除数据操作。
- 优先级队列(PriorityQueue):数据项按照关键字排序,关键字最小(或最大)的数据项通常位于队列最前面。
2.2 图解
栈的主要功能也很简单,无非就是队列的操作包括入队(add/offer)、出队(poll/remove)、查看队头元素(peek/element)。由于这种限制,队列中元素的移除顺序与添加顺序相想通,体现了先进先出的特性。
实现的基本方式:
- 顺序存储结构:使用数组实现的顺序队列需要维护一个队尾指针,并注意处理数组边界溢出的问题,通常通过循环队列的方式来优化。
- 链式存储结构:链式队列使用链表实现,每个节点包含数据和指向下一个节点的指针,这种结构可以灵活地处理队列的扩展和收缩。
2.2 结构
java中的队列,几乎都与Collection有关。使用队列时可以通过ArrayList和LinkedList等数据结构去实现,也是给足了选择性。
Queue
Deque
PriorityQueue
jdk中的接口也很简洁
Queue
Deque
PriorityQueue
主要的三个常用功能:
boolean add(E e); / boolean offer(E e); | 将元素添加到队列末尾,若添加成功则返回true。 |
E poll(); / E remove(); | 从队首删除并返回该元素。 |
E peek(); / E element(); | 返回队首元素,但不删除。 |
2.3 使用
2.3.1 Queue
public class QueueTest {
public static void main(String[] args) {
// 创建一个队列
Queue<Integer> queue = new LinkedList<>();
// 向队列中添加元素
queue.add(1);
queue.add(2);
queue.add(3);
// 查看队列头部元素
System.out.println("队列头部元素:" + queue.peek());
// 从队列中删除元素
System.out.println("出队元素:" + queue.poll());
// 遍历队列中的元素
System.out.println("队列中的元素:");
for (Integer element : queue) {
System.out.println(element);
}
}
}
// 结果
队列头部元素:1
出队元素:1
队列中的元素:
2
3
2.3.2 Deque
public class QueueTest {
public static void main(String[] args) {
// 创建一个栈
Deque<Integer> queue = new ArrayDeque<>();
// 向栈中添加元素
queue.push(1);
queue.push(2);
queue.push(3);
// 查看栈顶元素
System.out.println("栈顶元素:" + queue.peek());
// 从栈中删除元素
System.out.println("出栈元素:" + queue.pop());
// 遍历栈中的元素
System.out.println("栈中的元素:");
for (Integer element : queue) {
System.out.println(element);
}
}
}
// 结果
栈顶元素:3
出栈元素:3
栈中的元素:
2
1
2.3.3 PriorityQueue
public class PriorityQueueTest {
public static void main(String[] args) {
// 创建一个优先队列
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
// 向优先队列中添加元素
priorityQueue.add(3);
priorityQueue.add(1);
priorityQueue.add(2);
// 查看优先队列头部元素
System.out.println("优先队列头部元素:" + priorityQueue.peek());
// 从优先队列中删除元素
System.out.println("出队元素:" + priorityQueue.poll());
// 遍历优先队列中的元素
System.out.println("优先队列中的元素:");
for (Integer element : priorityQueue) {
System.out.println(element);
}
}
}
// 结果
优先队列头部元素:1
出队元素:1
优先队列中的元素:
2
3
3. 用途
- 消息处理与任务排队
- 异步处理:当消息或任务处理时间较长时,使用队列可以避免因长时间等待而造成的用户界面冻结或响应延迟。
- 生产者-消费者问题:在多线程环境中,队列可以用作生产者和消费者之间的缓冲区,生产者将数据入队,消费者从队列中取出数据进行处理。
- 数据结构和算法实现
- 广度优先搜索(BFS):在图算法中,队列用于实现BFS,以逐层访问节点的方式遍历图结构。
- 网络请求管理
- 请求缓存:服务器端可以使用队列来缓存和管理来自客户端的请求,以便按接收顺序进行处理。
- 缓存系统
- 数据缓冲:队列用于临时存储数据,平衡读写操作,提高系统的响应速度和吞吐量。
- 游戏开发
- 玩家动作排队:在游戏中,玩家的动作可以排队处理,确保游戏的公平性和逻辑正确性。
- 日志记录
- 日志排序:应用程序使用队列来收集日志信息,确保日志按照产生的顺序被记录和处理。
4. 总结
Java中的队列是一种遵循先进先出(FIFO)原则的数据结构,与栈的后进先出(LIFO)特性形成对比。队列在Java的集合框架中具有重要地位,广泛应用于各种数据处理场景,如任务调度、缓冲数据等。