Java队列- Java中的队列
Java 队列
在这一部分中,我们将讨论关于Java队列的一些重要要点。
- java.util.Queue interface is a subtype of java.util.Collection interface.
- Just like a real-world queue (for instance, in a bank or at ATM), Queue inserts elements at the end of the queue and removes from the beginning of the queue.
- Java Queue represents an ordered list of elements.
- Java Queue follows FIFO order to insert and remove it’s elements. FIFO stands for First In First Out.
- Java Queue supports all methods of Collection interface.
- Most frequently used Queue implementations are LinkedList, ArrayBlockingQueue and PriorityQueue.
- BlockingQueues do not accept null elements. If we perform any null related operation, it throws NullPointerException.
- BlockingQueues are used to implement Producer/Consumer based applications.
- BlockingQueues are thread-safe.
- All Queues which are available in java.util package are Unbounded Queues and Queues which are available in java.util.concurrent package are Bounded Queues.
- All Deques are not thread-safe.
- ConcurrentLinkedQueue is an unbounded thread-safe Queue based on linked nodes.
- All Queues supports insertion at the tail of the queue and removal at the head of the queue, except Deques.
- Deques are queues but they support element insertion and removal at both ends.
Java 队列类图
Java队列方法
在这一部分,我们将讨论一些有用且常用的Java队列方法。
- 获取Set中元素的数量。
检查Set是否为空。
如果Set包含指定的元素,则返回true。
返回一个遍历Set中元素的迭代器。元素的返回顺序没有特定规定。
从Set中移除包含在指定集合中的所有元素(可选操作)。
仅保留Set中包含在指定集合中的元素(可选操作)。
从Set中删除所有元素。
检索并移除这个队列的头部。
检索并移除这个队列的头部,如果这个队列为空则返回null。
检索但不移除这个队列的头部,如果这个队列为空则返回null。
如果立即插入指定元素不会违反容量限制,则将指定元素插入此队列。
检索但不移除这个队列的头部。
如果立即插入指定元素不会违反容量限制,返回true并在成功插入时抛出IllegalStateException。
返回一个包含Set中所有元素的数组。如果Set对其迭代器返回元素的顺序有任何保证,此方法必须以同样的顺序返回元素。
Java 队列基础
由于Java Queue继承了Java Collection,因此它也支持所有Collection接口操作。让我们在下面的示例中探索一些简单的操作。
package com.Olivia.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();
}
}
输出:
[one, two, three, four]
[one, two, four]
Queue Size: 3
Queue Contains element 'two' or not? : true
将Java数组转换为队列
在这里,我们可以通过一个简单的例子来探索如何使用“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);
}
}
当我们运行上述程序时,我们将得到以下输出:
[one, two, three, four, five]
将Java队列转换为数组。
在这里,我们将通过一个简单的例子探讨如何使用“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));
}
}
当我们运行以上程序时,我们将得到以下输出:
[one, two, three, four, five]
Java队列的常见操作
Java队列支持Collection接口支持的所有操作以及一些其他操作。它以两种形式几乎支持所有操作。
- One set of operations throws an exception if the operation fails.
- The other set of operations returns a special value if the operation fails.
以下表格简要说明了所有队列的常见操作。
Operation | Throws exception | Special value |
---|---|---|
Insert | add(e) | offer(e) |
Remove | remove() | poll() |
Examine | element() | peek() |
在接下来的章节中,我们会逐一介绍每个操作,并使用一些有用的例子进行详细讨论。
Java 队列的插入操作
在本节中,我们将详细讨论Java队列的插入操作,并提供一些有用的示例。如果此操作成功执行,它将返回”true”值。正如我们所知,队列支持两种形式的插入操作。
- Queue.add(e):
It throws an exception if the operation fails.- Queue.offer(e):
It returns a special value if the operation fails.
请注意:这里的特殊值可以是“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);
}
}
运行以上程序时,我们将得到以下输出:
true
true
[one, two]
Exception in thread "main" java.lang.IllegalStateException: Queue full
由于我们的队列仅限于两个元素,当我们尝试使用BlockingQueue.add()添加第三个元素时,就会抛出上述异常。
排队的 offer() 操作
offer()操作用于将新元素插入队列。如果成功执行插入操作,它将返回”true”;否则,它将返回”false”。让我们开发一个简单的示例来展示这个功能。
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);
}
}
当我们运行上述程序时,我们将获得如下输出:
true
true
[one, two]
false
[one, two]
由于我们的队列限制了只能包含两个元素,在我们试图使用BlockingQueue.offer()操作添加第三个元素时,它返回了”false”值,就像上面所示。
Java 队列的删除操作
在本部分中,我们将详细讨论Java队列删除操作,并提供一些有用的示例。如果删除成功,删除操作将返回队列的头元素。正如我们所知,队列支持两种形式的删除操作:
- Queue.remove():
It throws an exception if the operation fails.- Queue.poll():
It returns a special value if the operation fails.
请注意:这里特殊的值可以是“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());
}
}
当我们运行上述程序时,我们将获得以下输出结果:
[one, two]
one
two
Exception in thread "main" java.util.NoSuchElementException
因为队列只有两个元素,当我们尝试第三次调用remove()方法时,它会抛出上述的异常。注意:Queue.remove(element)方法用于从队列中删除指定的元素。如果删除成功,它会返回“true”值,否则返回“false”值。
队列的poll()操作
使用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());
}
}
当我们运行上面的程序时,我们会得到以下输出结果:
[one, two]
one
two
null
由于我们的队列只有两个元素,当我们尝试第三次调用poll()方法时,返回的值为null,如上所示。
Java队列检查操作
在这个部分,我们将详细讨论Java队列的检查操作,并附上一些有用的示例。如果此操作成功执行,它将返回队列的头元素而不移除它。正如我们所知,队列支持两种形式的检查操作:
- Queue.element():
It throws an exception if the operation fails.- Queue.peek():
It returns a special value if the operation fails.
请注意:这里的特殊值可以是“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());
}
}
输出:当我们运行上述程序时,我们将得到以下输出:
one
[one]
Exception in thread "main" java.util.NoSuchElementException
如果我们试图在空队列上调用element()方法,就会像上面显示的那样抛出一个异常。
查询队列的顶部元素。
使用 peek() 操作可以从队列头部检索一个元素,而不将其移除。如果检索操作成功,它会返回队列的头部元素。否则,返回 null 值。让我们开发一个简单的示例来演示这个功能。
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());
}
}
当我们运行以上程序时,我们会得到以下输出。
one
[one]
null
如果我们在空队列上尝试调用peek()方法,它会返回null值,但是不会像上面那样抛出异常。
Java队列分类
在Java中,我们可以找到许多队列实现。我们可以将它们广泛分为以下两种类型
- Bounded Queues
- Unbounded Queues
Bounded Queues(有界队列)是通过容量限制的队列,这意味着我们需要在创建时提供队列的最大容量大小。例如ArrayBlockingQueue(见之前的示例)。Unbounded Queues(无界队列)是没有容量限制的队列,这意味着我们不需要提供队列的大小。例如LinkedList(见之前的示例)。所有在java.util包中可用的队列都是无界队列,而在java.util.concurrent包中可用的队列都是有界队列。换句话说,我们可以广泛将它们归类为以下两种类型:
- Blocking Queues
- Non-Blocking Queues
所有实现BlockingQueue接口的队列都是阻塞队列,其余的队列都是非阻塞队列。阻塞队列会在完成任务或超时前一直阻塞,而非阻塞队列则不会。一些队列是双端队列,而另一些队列是优先级队列。
阻塞队列的操作
除了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队列示例能帮助你入门队列集合编程。如果你喜欢我的教程,有任何建议、问题或打字错误,请给我留言。谢谢。