1.队列定义:
在 Java 中,队列(Queue)是一种常用的数据结构,属于 java.util 包。Queue 接口继承自 Collection 接口,定义了一些基本操作,如入队、出队、查看队列头部等。Java 提供了多种实现 Queue 接口的类,这些类可以满足不同的使用需求。
2.Java 队列的常见实现
LinkedList:实现了 Queue 接口的一个常用类。它既可以作为队列使用,也可以作为双端队列使用。
PriorityQueue:实现了 Queue 接口,提供了基于优先级的队列,其中的元素按照自然顺序或构造时指定的比较器顺序排列。
I.ArrayDeque:实现了 Deque 接口,它也可以用作队列,提供了一个数组实现的双端队列。
ArrayDeque 是 Java 中的一个双端队列实现,提供了对队列两端的高效操作。它基于动态数组实现,因此在绝大多数情况下,它比 LinkedList 更高效,尤其是在频繁插入和删除操作时。以下是关于 ArrayDeque 的一些详细信息和使用示例:
i.特性
- 动态数组实现:ArrayDeque 使用动态数组来存储元素,这使得它在大多数情况下能够提供比链表更高的性能。
- 不支持 null 元素:ArrayDeque 不允许存储 null 元素。如果尝试插入 null,会抛出 NullPointerException。
- 非线程安全:ArrayDeque 是非线程安全的。如果在多线程环境中使用,应该使用适当的同步机制或者考虑使用 ConcurrentLinkedDeque。
- 不支持容量限制:ArrayDeque 在创建时不会设置固定容量,它会根据需要动态调整大小。
ii.常用方法
添加元素:
- addFirst(E e):在队列的前端插入元素。
- addLast(E e):在队列的尾部插入元素。
- offerFirst(E e):在队列的前端插入元素,如果队列已满,则返回 false。
- offerLast(E e):在队列的尾部插入元素,如果队列已满,则返回 false。
删除元素:
- removeFirst():移除并返回队列前端的元素。
- removeLast():移除并返回队列尾部的元素。
- pollFirst():移除并返回队列前端的元素,如果队列为空,则返回 null。
- pollLast():移除并返回队列尾部的元素,如果队列为空,则返回 null。
访问元素:
- peekFirst():查看队列前端的元素,但不移除它。
- peekLast():查看队列尾部的元素,但不移除它。
示例代码
以下是一个使用 ArrayDeque 的示例,展示了如何进行基本的操作:
import java.util.ArrayDeque;
import java.util.Deque;
public class ArrayDequeExample {
public static void main(String[] args) {
Deque<String> deque = new ArrayDeque<>();
// 添加元素到队列的两端
deque.addFirst("First");
deque.addLast("Last");
deque.offerFirst("New First");
deque.offerLast("New Last");
// 打印队列内容
System.out.println("Deque contents: " + deque);
// 访问并删除队列两端的元素
System.out.println("Removed from front: " + deque.removeFirst());
System.out.println("Removed from end: " + deque.removeLast());
// 访问但不删除元素
System.out.println("Head: " + deque.peekFirst());
System.out.println("Tail: " + deque.peekLast());
// 清空队列
deque.clear();
System.out.println("Deque after clearing: " + deque);
}
}
总结
ArrayDeque 是一个非常高效的双端队列实现,适用于大多数需要高效操作两端元素的场景。如果你的应用程序需要双端队列的支持,并且不需要线程安全,那么 ArrayDeque 是一个非常好的选择。
ConcurrentLinkedQueue 和 LinkedBlockingQueue:线程安全的队列实现,适用于多线程环境中的任务调度和线程间通信。
3.队列的基本操作
- add(E e):将元素添加到队列中,如果队列已满会抛出异常。
- offer(E e):将元素添加到队列中,如果队列已满,则返回 false。
- remove():移除并返回队列头部的元素,如果队列为空会抛出异常。
- poll():移除并返回队列头部的元素,如果队列为空则返回 null。
- peek():查看队列头部的元素,但不移除它。
- isEmpty():检查队列是否为空。
- size():返回队列中的元素数量。
示例代码
下面的示例展示了如何使用 LinkedList 和 PriorityQueue 来实现基本的队列操作:使用 LinkedList 实现队列
import java.util.LinkedList;
import java.util.Queue;
public class LinkedListQueueExample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
// 入队操作
queue.add("First");
queue.add("Second");
queue.add("Third");
// 查看队列内容
System.out.println("Queue: " + queue);
// 出队操作
System.out.println("Removed: " + queue.poll()); // 移除并返回队列头部元素
// 查看队列头部元素
System.out.println("Front: " + queue.peek()); // 返回但不移除队列头部元素
// 检查队列是否为空
System.out.println("Is queue empty? " + queue.isEmpty());
// 清空队列
queue.clear();
System.out.println("Queue after clearing: " + queue);
}
}
使用 PriorityQueue 实现队列
java
import java.util.PriorityQueue;
import java.util.Queue;
public class PriorityQueueExample {
public static void main(String[] args) {
Queue<Integer> queue = new PriorityQueue<>();
// 入队操作
queue.add(10);
queue.add(5);
queue.add(20);
// 查看队列内容
System.out.println("Queue: " + queue);
// 出队操作
System.out.println("Removed: " + queue.poll()); // 移除并返回优先级最高的元素(最小值)
// 查看队列头部元素
System.out.println("Front: " + queue.peek()); // 返回但不移除优先级最高的元素(最小值)
// 检查队列是否为空
System.out.println("Is queue empty? " + queue.isEmpty());
// 清空队列
queue.clear();
System.out.println("Queue after clearing: " + queue);
}
}
总结
LinkedList:适合一般的队列操作,支持双端操作。
PriorityQueue:适合需要按优先级处理元素的场景。
ArrayDeque:适合需要高效双端操作的场景。
ConcurrentLinkedQueue 和 LinkedBlockingQueue:适合多线程环境下使用。
选择合适的队列实现可以根据实际的需求和性能考虑来决定。