Java Queue 佇列
Queue 是先進先出(FIFO)的資料結構介面,元素從尾端加入,從頭端取出。
引入套件
import java.util.Queue;
import java.util.LinkedList;
import java.util.ArrayDeque;
import java.util.PriorityQueue;
建立 Queue
// 使用 LinkedList
Queue<String> queue1 = new LinkedList<>();
// 使用 ArrayDeque(推薦)
Queue<String> queue2 = new ArrayDeque<>();
// 優先佇列
Queue<Integer> pq = new PriorityQueue<>();
基本操作
Queue<String> queue = new LinkedList<>();
// 入列
queue.add("A"); // 失敗時拋例外
queue.offer("B"); // 失敗時回傳 false
// 查看頭端(不移除)
String head1 = queue.element(); // 空時拋例外
String head2 = queue.peek(); // 空時回傳 null
// 出列
String item1 = queue.remove(); // 空時拋例外
String item2 = queue.poll(); // 空時回傳 null
// 其他
int size = queue.size();
boolean empty = queue.isEmpty();
方法比較
| 操作 | 拋例外 | 回傳特殊值 |
|---|---|---|
| 入列 | add(e) | offer(e) |
| 出列 | remove() | poll() |
| 查看 | element() | peek() |
Deque 雙端佇列
Deque<String> deque = new ArrayDeque<>();
// 頭端操作
deque.addFirst("A");
deque.offerFirst("B");
String first = deque.removeFirst();
String peekFirst = deque.peekFirst();
// 尾端操作
deque.addLast("C");
deque.offerLast("D");
String last = deque.removeLast();
String peekLast = deque.peekLast();
PriorityQueue 優先佇列
// 最小堆(預設)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.addAll(Arrays.asList(5, 1, 3, 2, 4));
while (!minHeap.isEmpty()) {
System.out.print(minHeap.poll() + " "); // 1 2 3 4 5
}
// 最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
maxHeap.addAll(Arrays.asList(5, 1, 3, 2, 4));
while (!maxHeap.isEmpty()) {
System.out.print(maxHeap.poll() + " "); // 5 4 3 2 1
}
自訂排序
record Task(String name, int priority) {}
PriorityQueue<Task> tasks = new PriorityQueue<>(
Comparator.comparingInt(Task::priority)
);
tasks.add(new Task("Low", 3));
tasks.add(new Task("High", 1));
tasks.add(new Task("Medium", 2));
while (!tasks.isEmpty()) {
System.out.println(tasks.poll().name());
}
// High
// Medium
// Low
實用範例
BFS 廣度優先搜尋
public static void bfs(Map<Integer, List<Integer>> graph, int start) {
Queue<Integer> queue = new LinkedList<>();
Set<Integer> visited = new HashSet<>();
queue.offer(start);
visited.add(start);
while (!queue.isEmpty()) {
int node = queue.poll();
System.out.print(node + " ");
for (int neighbor : graph.getOrDefault(node, List.of())) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
queue.offer(neighbor);
}
}
}
}
任務排程
Queue<Runnable> taskQueue = new LinkedList<>();
taskQueue.offer(() -> System.out.println("Task 1"));
taskQueue.offer(() -> System.out.println("Task 2"));
taskQueue.offer(() -> System.out.println("Task 3"));
while (!taskQueue.isEmpty()) {
taskQueue.poll().run();
}
重點整理
Queue是 FIFO(先進先出)資料結構- 優先使用
ArrayDeque而非LinkedList offer/poll/peek較安全,失敗不拋例外Deque支援雙端操作PriorityQueue依優先順序出列- 常用於 BFS、任務排程等場景