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队列示例能帮助你入门队列集合编程。如果你喜欢我的教程,有任何建议、问题或打字错误,请给我留言。谢谢。

发表回复 0

Your email address will not be published. Required fields are marked *