Java中的集合框架Queue接口详解
字数 1037 2025-11-07 12:34:03
Java中的集合框架Queue接口详解
描述
Queue是Java集合框架中一个重要的接口,它专门用于处理先进先出(FIFO)的数据结构。除了基本的集合操作外,Queue还提供额外的插入、提取和检查操作,这些操作通常以两种形式存在:一种在操作失败时抛出异常,另一种返回特殊值(如null或false)。Queue接口是许多高级数据结构的基础,广泛应用于任务调度、消息传递等场景。
核心概念与分类
- Queue的基本特性:元素按FIFO顺序处理,但某些实现(如PriorityQueue)可能根据优先级排序
- 操作类型对比:
- 抛出异常:add(e), remove(), element()
- 返回特殊值:offer(e), poll(), peek()
- Queue的主要子接口:
- Deque:双端队列,支持两端操作
- BlockingQueue:阻塞队列,支持线程安全的阻塞操作
- TransferQueue:传输队列,支持生产者-消费者模式
Queue接口详解
1. 基本操作方法
-
插入操作:
// 添加元素,成功返回true,失败抛出IllegalStateException boolean add(E e); // 添加元素,成功返回true,失败返回false boolean offer(E e); -
移除操作:
// 移除并返回队列头部的元素,队列为空时抛出NoSuchElementException E remove(); // 移除并返回队列头部的元素,队列为空时返回null E poll(); -
检查操作:
// 返回队列头部的元素但不移除,队列为空时抛出NoSuchElementException E element(); // 返回队列头部的元素但不移除,队列为空时返回null E peek();
2. Queue的主要实现类
LinkedList - 基于链表的Queue实现
Queue<String> queue = new LinkedList<>();
queue.offer("A"); // 队列: [A]
queue.offer("B"); // 队列: [A, B]
queue.offer("C"); // 队列: [A, B, C]
String head = queue.poll(); // 返回"A",队列变为[B, C]
String peek = queue.peek(); // 返回"B",队列不变[B, C]
PriorityQueue - 基于优先堆的无界优先级队列
// 自然顺序(最小堆)
Queue<Integer> pq = new PriorityQueue<>();
pq.offer(5);
pq.offer(1);
pq.offer(3);
while (!pq.isEmpty()) {
System.out.println(pq.poll()); // 输出: 1, 3, 5(从小到大)
}
// 自定义比较器(最大堆)
Queue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
maxHeap.offer(5);
maxHeap.offer(1);
maxHeap.offer(3);
while (!maxHeap.isEmpty()) {
System.out.println(maxHeap.poll()); // 输出: 5, 3, 1(从大到小)
}
3. BlockingQueue阻塞队列
BlockingQueue是Queue的重要扩展,提供了线程安全的阻塞操作:
ArrayBlockingQueue - 有界数组实现的阻塞队列
BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
// 生产者线程
new Thread(() -> {
try {
queue.put("A"); // 阻塞直到有空间
queue.put("B");
queue.put("C");
System.out.println("生产完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
// 消费者线程
new Thread(() -> {
try {
Thread.sleep(1000);
String item = queue.take(); // 阻塞直到有元素
System.out.println("消费: " + item);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
LinkedBlockingQueue - 基于链表的可选有界阻塞队列
// 无界队列(默认Integer.MAX_VALUE)
BlockingQueue<Integer> unbounded = new LinkedBlockingQueue<>();
// 有界队列
BlockingQueue<Integer> bounded = new LinkedBlockingQueue<>(100);
4. Deque双端队列
Deque扩展了Queue,支持在两端进行插入和删除操作:
ArrayDeque - 基于数组的高效双端队列实现
Deque<String> deque = new ArrayDeque<>();
// 作为栈使用(LIFO)
deque.push("A"); // 栈: [A]
deque.push("B"); // 栈: [B, A]
deque.push("C"); // 栈: [C, B, A]
String top = deque.pop(); // 返回"C",栈变为[B, A]
// 作为队列使用(FIFO)
deque.offerLast("X"); // 队列: [B, A, X]
deque.offerLast("Y"); // 队列: [B, A, X, Y]
String first = deque.pollFirst(); // 返回"B",队列变为[A, X, Y]
5. 并发队列实现
ConcurrentLinkedQueue - 基于链接节点的无界线程安全队列
Queue<String> concurrentQueue = new ConcurrentLinkedQueue<>();
// 多线程安全操作
Runnable task = () -> {
for (int i = 0; i < 100; i++) {
concurrentQueue.offer(Thread.currentThread().getName() + "-" + i);
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
// 等待线程完成,然后消费所有元素
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
while (!concurrentQueue.isEmpty()) {
System.out.println(concurrentQueue.poll());
}
使用场景总结
- LinkedList:简单的FIFO队列需求
- PriorityQueue:需要按优先级处理元素的场景
- ArrayBlockingQueue:固定大小的生产者-消费者模式
- LinkedBlockingQueue:可选的边界限制,高吞吐量场景
- ArrayDeque:需要栈或双端队列功能的场景
- ConcurrentLinkedQueue:高并发环境下的无界队列需求
Queue接口及其实现提供了丰富的数据结构选择,理解它们的特性和适用场景对于编写高效的Java程序至关重要。