📚 Java 23 集合框架详解:Queue
接口及实现类(PriorityQueue
、LinkedList
)
📖 1. 概述
Queue
接口是 Java 集合框架中的一种 先进先出(FIFO) 数据结构,广泛用于任务调度、缓存、异步数据处理等场景。Queue
接口的主要实现类包括:
PriorityQueue
:基于优先级排序的队列。LinkedList
:作为队列使用时,按插入顺序存储元素。
在 Java 23 中,Queue
接口支持多种操作,例如:
- 插入元素:
offer()
- 获取元素:
peek()
- 删除元素:
poll()
本篇将详细介绍 PriorityQueue
和 LinkedList
的使用案例、底层实现、性能优化方案及多线程优化。
📋 2. Queue
接口常用方法
方法 | 描述 | 返回值 |
---|---|---|
offer(E e) | 将元素插入队列(不抛异常) | true 或 false |
add(E e) | 将元素插入队列(队列满时抛异常) | true 或抛异常 |
peek() | 获取但不删除队首元素(队列为空返回 null ) | 元素或 null |
element() | 获取但不删除队首元素(队列为空抛异常) | 元素或抛异常 |
poll() | 获取并删除队首元素(队列为空返回 null ) | 元素或 null |
remove() | 获取并删除队首元素(队列为空抛异常) | 元素或抛异常 |
📋 3. PriorityQueue
详解
✅ 3.1 特点
- 基于堆实现,默认使用 最小堆,元素按 自然顺序 排序。
- 可以指定自定义的 比较器 来定义排序规则。
- 不允许存储
null
值。 - 插入和删除操作的时间复杂度为 O(log n)。
🔧 3.2 使用案例
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
// 创建一个默认的 PriorityQueue
PriorityQueue<Integer> queue = new PriorityQueue<>();
// 插入元素
queue.offer(10);
queue.offer(5);
queue.offer(20);
// 遍历队列
System.out.println("Priority Queue Elements:");
queue.forEach(System.out::println);
// 获取并删除队首元素
System.out.println("Polled Element: " + queue.poll());
// 查看队首元素
System.out.println("Peek Element: " + queue.peek());
}
}
输出:
Priority Queue Elements:
5
10
20
Polled Element: 5
Peek Element: 10
🔧 3.3 使用自定义排序的 PriorityQueue
import java.util.PriorityQueue;
import java.util.Comparator;
public class CustomPriorityQueueExample {
public static void main(String[] args) {
// 按降序排序
PriorityQueue<Integer> queue = new PriorityQueue<>(Comparator.reverseOrder());
queue.offer(10);
queue.offer(5);
queue.offer(20);
// 遍历队列
queue.forEach(System.out::println);
}
}
输出:
20
10
5
🛠 3.4 优化方案
- 避免存储
null
值,因为PriorityQueue
不支持null
。 - 合理选择排序规则,根据业务需求使用 自然顺序 或 自定义比较器。
- 在大数据场景下,考虑使用
ArrayDeque
代替,如果排序不是必要的。
⚠️ 3.5 多线程优化
PriorityQueue
是 线程不安全的,可以使用 PriorityBlockingQueue
替代。
✅ 使用 PriorityBlockingQueue
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueExample {
public static void main(String[] args) {
PriorityBlockingQueue<Integer> queue = new PriorityBlockingQueue<>();
queue.offer(10);
queue.offer(5);
queue.offer(20);
queue.forEach(System.out::println);
}
}
📋 4. LinkedList
详解
✅ 4.1 特点
- 基于双向链表实现,既可以作为 列表 使用,也可以作为 队列 使用。
- 允许存储
null
值。 - 插入和删除操作的时间复杂度为 O(1)。
🔧 4.2 使用案例
import java.util.LinkedList;
import java.util.Queue;
public class LinkedListQueueExample {
public static void main(String[] args) {
// 创建一个 LinkedList 作为队列使用
Queue<String> queue = new LinkedList<>();
// 插入元素
queue.offer("Alice");
queue.offer("Bob");
queue.offer("Charlie");
// 遍历队列
System.out.println("Queue Elements:");
queue.forEach(System.out::println);
// 获取并删除队首元素
System.out.println("Polled Element: " + queue.poll());
// 查看队首元素
System.out.println("Peek Element: " + queue.peek());
}
}
输出:
Queue Elements:
Alice
Bob
Charlie
Polled Element: Alice
Peek Element: Bob
🛠 4.3 优化方案
- 避免频繁的随机访问,因为
LinkedList
的随机访问性能较差。 - 优先使用
ArrayDeque
,如果不需要线程安全且操作较频繁。
⚠️ 4.4 多线程优化
LinkedList
是 线程不安全的,在多线程环境中可以使用 ConcurrentLinkedQueue
替代。
✅ 使用 ConcurrentLinkedQueue
import java.util.concurrent.ConcurrentLinkedQueue;
public class ConcurrentLinkedQueueExample {
public static void main(String[] args) {
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
queue.offer("Alice");
queue.offer("Bob");
queue.forEach(System.out::println);
}
}
🔄 5. 两者对比总结
特性 | PriorityQueue | LinkedList |
---|---|---|
底层数据结构 | 堆 | 双向链表 |
排序方式 | 自然顺序/自定义排序 | 插入顺序 |
是否允许 null 值 | 否 | 是 |
插入/删除性能 | O(log n) | O(1) |
适用场景 | 优先级任务调度 | 普通队列操作 |
🎯 6. 选择指南
场景 | 推荐实现类 |
---|---|
需要按优先级处理任务 | PriorityQueue |
需要普通队列操作 | LinkedList |
需要线程安全的队列 | PriorityBlockingQueue 或 ConcurrentLinkedQueue |
⚙️ 7. 总结
PriorityQueue
是一种 优先级队列,适用于按优先级排序的任务调度场景。LinkedList
是一种 双向链表,既可以作为列表使用,也可以作为队列使用,适用于普通队列操作。
在多线程环境中,建议使用 PriorityBlockingQueue
或 ConcurrentLinkedQueue
,以确保线程安全。根据实际业务场景选择合适的 Queue
实现类,可以显著提升应用的性能和代码的可读性。