Java 队列 – Java 中的队列
Java Queue 是 java.util 包中的一个接口,它扩展了 java.util.Collection 接口。与 Java List 一样,Java Queue 是有序元素(或对象)的集合,但它执行插入和删除操作的方式不同。我们可以使用 Queue 来存储元素,然后再处理这些元素。
Java 队列
在本节中,我们将讨论有关 Java 队列的一些要点:
- java.util.Queue 接口是 java.util.Collection 接口的子类型。
- 就像现实世界中的队列一样(例如,在银行或 ATM 中),队列在队列末尾插入元素并从队列开头删除。
- Java Queue 表示元素的有序列表。
- Java 队列遵循 FIFO 顺序插入和移除元素。FIFO 代表先进先出。
- Java Queue 支持 Collection 接口的所有方法。
- 最常用的队列实现是 LinkedList、ArrayBlockingQueue 和 PriorityQueue。
- BlockingQueues 不接受 null 元素。如果我们执行任何与 null 相关的操作,它会抛出 NullPointerException。
- BlockingQueues 用于实现基于生产者/消费者的应用程序。
- BlockingQueues 是线程安全的。
- java.util 包中可用的所有队列都是无界队列,而 java.util.concurrent 包中可用的队列都是有界队列。
- 并非所有双端队列都是线程安全的。
- ConcurrentLinkedQueue 是一个基于链接节点的无界线程安全队列。
- 除 Deque 外,所有队列都支持在队列尾部插入和在队列头部删除。
- 双端队列是队列,但它们支持在两端插入和删除元素。
Java 队列类图
Java Queue 接口扩展了 Collection 接口。Collection 接口扩展了 Iterable 接口。一些常用的 Queue 实现类有 LinkedList、PriorityQueue、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue 等……AbstractQueue 提供了 Queue 接口的骨架实现,以减少实现 Queue 的工作量。
Java 队列方法
在本节中,我们将讨论一些有用且经常使用的 Java 队列方法:
- int size():获取Set中元素的数量。
- boolean isEmpty():检查 Set 是否为空。
- boolean contains(Object o):如果此 Set 包含指定元素,则返回 true。
- 迭代器 iterator():返回此集合中元素的迭代器。返回的元素没有特定的顺序。
- boolean removeAll(Collection c):从此集合中删除指定集合中包含的所有元素(可选操作)。
- boolean retainAll(Collection c):仅保留此集合中包含在指定集合中的元素(可选操作)。
- void clear():从集合中删除所有元素。
- E remove():检索并删除此队列的头。
- E poll():检索并移除此队列的头,如果此队列为空,则返回 null。
- E peek(): Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.
- boolean offer(E e): Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions.
- E element(): Retrieves, but does not remove, the head of this queue.
- boolean add(E e): Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions, returning true upon success and throwing an IllegalStateException if no space is currently available.
- Object[] toArray(): Returns an array containing all of the elements in this set. If this set makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order.
Java Queue Basics
As Java Queue extends Java Collection, it also supports all Collection interface operations. Let’s explore some simple operations in the following example:
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:-
Queue Size: 3
Queue Contains element 'two' or not? : true
Java Array to Queue
Here we can explore how to convert a Java array to Queue using “Collections.addAll()” method with one simple example.
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:- When we run above program, We will get the following output:
Java Queue to Array
Here we will explore how to convert a Java Queue to a Java Array using “toArray()” with one simple example.
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:- When we run above program, We will get the following output:
Java Queue Common Operations
Java Queue supports all operations supported by Collection interface and some more operations. It supports almost all operations in two forms.
- One set of operations throws an exception if the operation fails.
- The other set of operations returns a special value if the operation fails.
The following table explains all Queue common operations briefly.
Operation | Throws exception | Special value |
---|---|---|
Insert | add(e) | offer(e) |
Remove | remove() | poll() |
Examine | element() | peek() |
We will pickup each operation and discuss them in-detail with some useful examples in the coming sections.
Java Queue Insert Operations
In this section, we will discuss about Java Queue Insert operation in-detail with some useful examples. If this operation performs successfully, it returns “true” value. As we know, Queue supports insert operation in two forms:
- Queue.add(e): It throws an exception if the operation fails.- Queue.offer(e): It returns a special value if the operation fails.
NOTE:- Here special value may be either “false” or “null”
Queue add() operation
The add() operation is used to insert new element into the queue. If it performs insert operation successfully, it returns “true” value. Otherwise it throws java.lang.IllegalStateException. Let us develop one simple example to demonstrate this functionality.
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:- When we run above program, We will get the following output:
true
true
Exception in thread "main" java.lang.IllegalStateException: Queue full
As our queue is limited to two elements, when we try to add third element using BlockingQueue.add(), it throws an exception as shown above.
Queue offer() operation
The offer() operation is used to insert new element into the queue. If it performs insert operation successfully, it returns “true” value. Otherwise it returns “false” value. Let us develop one simple example to demonstrate this functionality.
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:- When we run above program, We will get the following output:
true
true
false
As our queue is limited to two elements, when we try to add third element using BlockingQueue.offer() operation, it returns “false” value as shown above.
Java Queue Delete Operations
In this section, we will discuss about Java Queue Delete operation in-detail with some useful examples. The Delete operations returns the head element of the queue, if it performs successfully. As we know, Queue supports delete operation in two forms:
- Queue.remove(): It throws an exception if the operation fails.- Queue.poll(): It returns a special value if the operation fails.
NOTE:- Here special value may be either “false” or “null”
Queue remove() operation
The remove() operation is used to delete an element from the head of the queue. If it performs delete operation successfully, it returns the head element of the queue. Otherwise it throws java.util.NoSuchElementException. Let us develop one simple example to demonstrate this functionality.
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:- When we run above program, We will get the following output:
one
two
Exception in thread "main" java.util.NoSuchElementException
As our queue has only two elements, when we try to call remove() method for third time, it throws an exception as shown above. NOTE:- Queue.remove(element) is used to delete a specified element from the queue. If it performs delete operation successfully, it returns “true” value. Otherwise it returns “false” value.
Queue poll() operation
The poll() operation is used to delete an element from the head of the queue. If it performs delete operation successfully, it returns the head element of the queue. Otherwise it returns “null” value. Let us develop one simple example to demonstrate this functionality.
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:- When we run above program, We will get the following output:
one
two
null
As our queue has only two elements, when we try to call poll() method for third time, it returns null value as shown above.
Java Queue Examine Operations
In this section, we will discuss about Java Queue Examine operations in-detail with some useful examples. If this operation performs successfully, it returns the head element of the queue without removing it. As we know, Queue supports examine operation in two forms:
- Queue.element(): It throws an exception if the operation fails.- Queue.peek(): It returns a special value if the operation fails.
NOTE:- Here special value may be either “false” or “null”
Queue element() operation
The element() operation is used to retrieve an element from the head of the queue, without removing it. If it performs examine operation successfully, it returns the head element of the queue. Otherwise it throws java.util.NoSuchElementException. Let us develop one simple example to demonstrate this functionality.
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:- When we run above program, We will get the following output:
one
Exception in thread "main" java.util.NoSuchElementException
If we try to call element() method on empty Queue, it throws an exception as shown above.
Queue peek() operation
The peek() operation is used to retrieve an element from the head of the queue, without removing it. If it performs examine operation successfully, it returns the head element of the queue. Otherwise it returns null value. Let us develop one simple example to demonstrate this functionality.
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:- When we run above program, We will get the following output:
one
null
If we try to call peek() method on empty Queue, it returns null value, but does NOT throw an exception as shown above.
Java Queue Categories
In Java, we can find many Queue implementations. W can broadly categorize them into the following two types
- Bounded Queues
- Unbounded Queues
Bounded Queues are queues which are bounded by capacity that means we need to provide the max size of the queue at the time of creation. For example ArrayBlockingQueue (see previous example). Unbounded Queues are queues which are NOT bounded by capacity that means we should not provide the size of the queue. For example LinkedList (see previous example). 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. In other ways, W can broadly categorize them into the following two types:
- Blocking Queues
- Non-Blocking Queues
All Queues which implement BlockingQueue interface are BlockingQueues and rest are Non-Blocking Queues. BlockingQueues blocks until it finishes it’s job or time out, but Non-BlockingQueues do not. Some Queues are Deques and some queues are PriorityQueues.
BlockingQueue Operations
In addition to Queue’s two forms of operations, BlockingQueue’s supports two more forms as shown below.
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 |
Some operations are blocked until it finishes it’s job and other are blocked until time out. That’s all of a quick roundup on Queue in Java. I hope these Java Queue examples will help you in getting started with Queue collection programming. Please drop me a comment if you like my tutorials or have any suggestions or issues or type errors. Thank you.