Java Queue is an interface available in java.util package and extends java.util.Collection interface. Just like Java List, Java Queue is a collection of ordered elements (Or objects) but it performs insert and remove operations differently. We can use Queue to store elements before processing those elements.
在本节中,我们将讨论有关 Java 队列的一些要点:
- java.util.Queue 接口是 java.util.Collection 接口的子类型。
- 就像现实世界中的队列(例如,在银行或 ATM 中)一样,Queue 在队列末尾插入元素并从队列开头删除元素。
- Java 队列表示元素的有序列表。
- Java 队列遵循 FIFO 顺序插入和删除元素。 FIFO 代表先进先出。
- Java Queue 支持 Collection 接口的所有方法。
- 最常用的队列实现是 LinkedList、ArrayBlockingQueue 和 PriorityQueue。
- BlockingQueue 不接受 null 元素。如果我们执行任何与 null 相关的操作,它会抛出 NullPointerException。
- BlockingQueues 用于实现基于生产者/消费者的应用程序。
- BlockingQueue 是线程安全的。
- java.util 包中可用的所有队列都是无界队列,而 java.util.concurrent 包中可用的队列是有界队列。
- 所有双端队列都不是线程安全的。
- ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列。
- 除双端队列外,所有队列都支持在队列尾部插入和在队列头部删除。
- 双端队列是队列,但它们支持在两端插入和删除元素。
Java Queue interface extends Collection interface. Collection interface extends Iterable interface. Some of the frequently used Queue implementation classes are LinkedList, PriorityQueue, ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue, PriorityBlockingQueue etc… AbstractQueue provides a skeletal implementation of the Queue interface to reduce the effort in implementing Queue.
在本节中,我们将讨论一些有用且常用的 Java 队列方法:
- int size():获取Set中元素的数量。
- boolean isEmpty():检查 Set 是否为空。
- boolean contains(Object o):如果此 Set 包含指定元素,则返回 true。
- Iterator iterator():返回此集合中元素的迭代器。返回的元素没有特定的顺序。
- boolean removeAll(Collection c):从此集合中删除指定集合中包含的所有元素(可选操作)。
- boolean keepAll(Collection c):仅保留此集合中包含在指定集合中的元素(可选操作)。
- voidclear():从集合中删除所有元素。
- Eremove():检索并删除该队列的头部。
- E poll():检索并移除该队列的头部,如果该队列为空则返回null。
- E peek():检索但不删除此队列的头部,如果此队列为空,则返回 null。
- boolean Offer(E e):如果可以立即插入指定元素而不违反容量限制,则将指定元素插入此队列。
- E element():检索但不删除该队列的头。
- boolean add(E e):如果可以立即插入指定元素而不违反容量限制,则将指定元素插入此队列,成功时返回 true,如果当前没有可用空间,则抛出 IllegalStateException。
- Object[] toArray():返回一个包含该集合中所有元素的数组。如果此集合对其迭代器返回其元素的顺序做出任何保证,则此方法必须以相同的顺序返回元素。
由于Java Queue扩展了Java Collection,因此它也支持所有Collection接口操作。让我们在以下示例中探讨一些简单的操作:
package com.journaldev.queue;
import java.util.*;
public class QueueExample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("one");
queue.add("two");
queue.add("three");
queue.add("four");
System.out.println(queue);
queue.remove("three");
System.out.println(queue);
System.out.println("Queue Size: " + queue.size());
System.out.println("Queue Contains element 'two' or not? : " + queue.contains("two"));
// To empty the queue
queue.clear();
}
}
Output:-
[one, two, three, four]
[one, two, four]
Queue Size: 3
Queue Contains element 'two' or not? : true
这里我们可以通过一个简单的例子来探索如何使用“Collections.addAll()”方法将 Java 数组转换为队列。
import java.util.*;
public class ArrayToQueue {
public static void main(String[] args) {
String nums[] = {"one","two","three","four","five"};
Queue<String> queue = new LinkedList<>();
Collections.addAll(queue, nums);
System.out.println(queue);
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
[one, two, three, four, five]
这里我们将通过一个简单的例子来探讨如何使用“toArray()”将 Java 队列转换为 Java 数组。
import java.util.*;
public class QueueToArray {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("one");
queue.add("two");
queue.add("three");
queue.add("four");
queue.add("five");
String strArray[] = queue.toArray(new String[queue.size()]);
System.out.println(Arrays.toString(strArray));
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
[one, two, three, four, five]
Java Queue 支持 Collection 接口支持的所有操作以及更多操作。它支持两种形式的几乎所有操作。
- 如果操作失败,一组操作将引发异常。
- 如果操作失败,另一组操作将返回一个特殊值。
下表简要解释了所有 Queue 常见操作。
Operation |
Throws exception |
Special value |
Insert |
add(e) |
offer(e) |
Remove |
remove() |
poll() |
Examine |
element() |
peek() |
我们将在接下来的章节中介绍每个操作并通过一些有用的示例详细讨论它们。
在本节中,我们将通过一些有用的示例详细讨论 Java 队列插入操作。如果此操作执行成功,则返回“true”值。我们知道,Queue支持两种形式的插入操作:
- 队列.add(e):
如果操作失败,它会抛出异常。- Queue.offer(e):
如果操作失败,它会返回一个特殊值。
NOTE:-这里的特殊值可以是“false”或“null”
add() 操作用于向队列中插入新元素。如果成功执行插入操作,则返回“true”值。否则它会抛出 java.lang.IllegalStateException。让我们开发一个简单的示例来演示此功能。
import java.util.concurrent.*;
public class QueueAddOperation {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
System.out.println(queue.add("one"));
System.out.println(queue.add("two"));
System.out.println(queue);
System.out.println(queue.add("three"));
System.out.println(queue);
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
true
true
[one, two]
Exception in thread "main" java.lang.IllegalStateException: Queue full
由于我们的队列仅限于两个元素,因此当我们尝试使用 BlockingQueue.add() 添加第三个元素时,它会抛出异常,如上所示。
Offer() 操作用于将新元素插入队列。如果成功执行插入操作,则返回“true”值。否则返回“假”值。让我们开发一个简单的示例来演示此功能。
import java.util.concurrent.*;
public class QueueOfferOperation {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
System.out.println(queue.offer("one"));
System.out.println(queue.offer("two"));
System.out.println(queue);
System.out.println(queue.offer("three"));
System.out.println(queue);
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
true
true
[one, two]
false
[one, two]
由于我们的队列仅限于两个元素,因此当我们尝试使用 BlockingQueue.offer() 操作添加第三个元素时,它会返回“false”值,如上所示。
在本节中,我们将通过一些有用的示例详细讨论 Java 队列删除操作。如果执行成功,删除操作将返回队列的头元素。我们知道,Queue 支持两种形式的删除操作:
- 队列.remove():
如果操作失败,它会抛出异常。- Queue.poll():
如果操作失败,它会返回一个特殊值。
NOTE:-这里的特殊值可以是“false”或“null”
remove() 操作用于从队列头部删除一个元素。如果删除操作成功,则返回队列的头元素。否则它会抛出 java.util.NoSuchElementException。让我们开发一个简单的示例来演示此功能。
import java.util.*;
public class QueueRemoveOperation
{
public static void main(String[] args)
{
Queue<String> queue = new LinkedList<>();
queue.offer("one");
queue.offer("two");
System.out.println(queue);
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
[one, two]
one
two
Exception in thread "main" java.util.NoSuchElementException
由于我们的队列只有两个元素,当我们尝试第三次调用remove()方法时,它会抛出一个异常,如上所示。NOTE:-Queue.remove(element) 用于从队列中删除指定元素。如果成功执行删除操作,则返回“true”值。否则返回“假”值。
poll() 操作用于从队列头部删除一个元素。如果删除操作成功,则返回队列的头元素。否则返回“null”值。让我们开发一个简单的示例来演示此功能。
import java.util.*;
public class QueuePollOperation
{
public static void main(String[] args)
{
Queue<String> queue = new LinkedList<>();
queue.offer("one");
queue.offer("two");
System.out.println(queue);
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
[one, two]
one
two
null
由于我们的队列只有两个元素,当我们第三次尝试调用 poll() 方法时,它会返回 null 值,如上所示。
在本节中,我们将通过一些有用的示例详细讨论 Java 队列检查操作。如果此操作执行成功,它将返回队列的头元素而不删除它。我们知道,Queue 支持两种形式的检查操作:
- 队列.element():
如果操作失败,它会抛出异常。- Queue.peek():
如果操作失败,它会返回一个特殊值。
NOTE:-这里的特殊值可以是“false”或“null”
element() 操作用于从队列头部检索元素,而不删除它。如果检查操作成功,则返回队列的头元素。否则它会抛出 java.util.NoSuchElementException。让我们开发一个简单的示例来演示此功能。
import java.util.*;
public class QueueElementOperation {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("one");
System.out.println(queue.element());
System.out.println(queue);
queue.clear();
System.out.println(queue.element());
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
one
[one]
Exception in thread "main" java.util.NoSuchElementException
如果我们尝试在空队列上调用 element() 方法,它会抛出异常,如上所示。
peek() 操作用于从队列头部检索元素,但不删除它。如果检查操作成功,则返回队列的头元素。否则返回空值。让我们开发一个简单的示例来演示此功能。
import java.util.*;
public class QueuePeekOperation {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("one");
System.out.println(queue.peek());
System.out.println(queue);
queue.clear();
System.out.println(queue.peek());
}
}
Output:-当我们运行上面的程序时,我们将得到以下输出:
one
[one]
null
如果我们尝试在空队列上调用 peek() 方法,它会返回 null 值,但不会抛出异常,如上所示。
在Java中,我们可以找到很多Queue的实现。 W大致可以分为以下两类
有界队列是受容量限制的队列,这意味着我们需要在创建时提供队列的最大大小。例如 ArrayBlockingQueue(参见前面的示例)。无界队列是不受容量限制的队列,这意味着我们不应该提供队列的大小。例如 LinkedList(参见前面的示例)。 java.util 包中可用的所有队列都是无界队列,而 java.util.concurrent 包中可用的队列是有界队列。从其他方面来说,W可以将它们大致分为以下两种类型:
所有实现BlockingQueue接口的队列都是阻塞队列,其余的都是非阻塞队列。 BlockingQueues 会阻塞,直到完成工作或超时,但 Non-BlockingQueues 不会。有些队列是Deque,有些队列是PriorityQueue。
除了 Queue 的两种操作形式外,BlockingQueue 还支持两种形式,如下所示。
Operation |
Throws exception |
Special value |
Blocks |
Times out |
Insert |
add(e) |
offer(e) |
put(e) |
offer(e, time, unit) |
Remove |
remove() |
poll() |
take() |
poll(time, unit) |
Examine |
element() |
peek() |
N/A |
N/A |
一些操作会被阻止,直到完成其工作,而其他操作会被阻止,直到超时。这就是关于 Java 队列的所有快速综述。我希望这些 Java 队列示例将帮助您开始队列集合编程。如果您喜欢我的教程或有任何建议、问题或输入错误,请给我评论。谢谢。