在Java集合框架中, Queue是一个接口,它继承自Collection接口。Queue代表了一个队列数据结构,这种结构通常遵循先进先出(FIFO)的原则。这意味着元素是按照它们被添加到队列中的顺序进行处理的。
Queue:
主要方法:
- boolean add(E e):确保此队列包含指定的元素(可选操作)。如果队列已满,抛出IllegalStateException。
- E remove():检索并移除此队列的头部。如果队列为空,则抛出NoSuchElementException。
- E poll():检索并移除此队列的头部,如果队列为空,则返回null。
- E element():检索但不移除此队列的头部。如果队列为空,则抛出NoSuchElementException。
- E peek():检索但不移除此队列的头部,如果队列为空,则返回null。
- Java 集合框架还提供了Deque接口,它是Queue的子接口,代表了一个双端队列,允许在队列的两端进行插入和删除操作。LinkedList类实现了Deque接口,因此它可以作为一个双端队列使用。
- 除了LinkedList,Java 集合框架还提供了其他实现了Queue接口的类,如PriorityQueue,它是一个基于优先级堆的无界优先级队列,可以根据元素的自然顺序或者构造时提供的Comparator进行排序。
实现类
Java集合框架提供了多种Queue
的实现, 每种实现都有其特定的用途和特性:
LinkedList
: 实现了List
和接口Deque
,因此它既可以作为列表,也可以作为双端队列使用。PriorityQueue
: 一个基于优先级堆的无界队列,元素的出队顺序基于其自然顺序或者构造队列时指定的Comparator
。ArrayDeque
: 一个基于数组的双端队列和栈实现,是一个循环数组。
使用LinkedList作为实现Queue
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
// 向队列中添加元素
queue.offer(1);
queue.offer(2);
queue.offer(3);
// 访问队列头部的元素但不移除
System.out.println("队列头部元素: " + queue.peek()); // 输出: 队列头部元素: 1
// 移除并返回队列头部的元素
System.out.println("移除的元素: " + queue.poll()); // 输出: 移除的元素: 1
// 再次访问队列头部的元素
System.out.println("现在队列头部元素: " + queue.peek()); // 输出: 现在队列头部元素: 2
// 遍历队列
for (Integer num : queue) {
System.out.println(num);
}
// 输出: 2
// 3
}
}
注意事项
当使用Queue时,要根据你的具体需求选择合适的实现。例如,如果你需要保持元素的排序,那么PriorityQueue可能是一个更好的选择。
Queue的线程安全性因实现而异。例如,LinkedList实现的Queue不是线程安全的。如果你需要在多线程环境下使用,请考虑使用BlockingQueue或ConcurrentLinkedQueue等线程安全的实现。
PriorityQueue:
在Java中, PriorityQueue是一个基于优先级堆的无界优先级队列。它不允许元素null,并且队列的头部是根据指定的排序方式被认为是具有最小值的元素。如果未指定排序方式,则使用元素的自然顺序。
以下是如何在Java中使用PriorityQueue的基本步骤:
1. 创建PriorityQueue实例 :
你可以创建一个空的PriorityQueue, 或者传入一个初始集合( Collection) 来初始化队列。
2. 添加元素 :
使用add()或方法offer()将元素添加到队列中。3. 访问和移除头部元素 :
使用方法peek()访问队列头部的元素, 但不移除它。使用方法poll()访问并移除队列头部的元素。4. 自定义排序 :
如果你想要自定义元素的排序方式, 可以创建一个Comparator并将其传递给PriorityQueue的构造函数。
简单的PriorityQueue示例
import java.util.Comparator;
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
// 创建一个空的PriorityQueue
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
// 添加元素
priorityQueue.add(4);
priorityQueue.add(2);
priorityQueue.add(1);
priorityQueue.add(3);
// 访问头部元素但不移除
System.out.println("队列头部元素: " + priorityQueue.peek());
// 移除并访问头部元素
while (!priorityQueue.isEmpty()) {
System.out.println("移除的元素: " + priorityQueue.poll());
}
// 创建一个具有自定义排序的PriorityQueue
PriorityQueue<String> customPriorityQueue = new PriorityQueue<>(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s2.length() - s1.length(); // 根据字符串长度降序排序
}
});
// 添加元素到自定义排序的PriorityQueue
customPriorityQueue.add("apple");
customPriorityQueue.add("banana");
customPriorityQueue.add("cherry");
// 访问并移除自定义排序的PriorityQueue的头部元素
while (!customPriorityQueue.isEmpty()) {
System.out.println("移除的元素: " + customPriorityQueue.poll());
}
}
}
在这个示例中,我们首先创建了一个空的PriorityQueue,并向其中添加了整数。然后,我们访问并移除了队列的头部元素。接着,我们创建了一个具有自定义排序的PriorityQueue,该队列根据字符串的长度进行降序排序,并向其中添加了字符串。最后,我们访问并移除了这个自定义排序队列的头部元素。