Java队列– Java队列

时间:2020-02-23 14:36:46  来源:igfitidea点击:

Java Queue是java.util包中可用的接口,并且扩展了java.util.Collection接口。
就像Java List一样,Java Queue是有序元素(或者对象)的集合,但是它执行插入和删除操作的方式有所不同。
我们可以使用Queue来存储元素,然后再处理这些元素。

Java队列

在本节中,我们将讨论有关Java Queue的一些重要点:

  • java.util.Queue接口是java.util.Collection接口的子类型。

  • 就像现实世界中的队列(例如,在银行或者ATM中)一样,Queue在队列的末尾插入元素,并从队列的开头删除元素。

  • Java Queue表示元素的有序列表。

  • Java Queue按照FIFO的顺序插入和删除它的元素。
    FIFO代表先进先出。

  • Java Queue支持Collection接口的所有方法。

  • 最常用的Queue实现是LinkedList,ArrayBlockingQueue和PriorityQueue。

  • BlockingQueues不接受空元素。
    如果执行任何与null相关的操作,则将引发NullPointerException。

  • BlockingQueues用于实现基于生产者/消费者的应用程序。

  • BlockingQueues是线程安全的。

  • java.util包中可用的所有队列都是"无界队列",而java.util.concurrent包中可用的所有队列是"有界队列"。

  • 所有双端队列都不是线程安全的。

  • ConcurrentLinkedQueue是基于链接节点的无界线程安全队列。

  • 除双端队列外,所有队列均支持在队列尾部插入和在队列头部移除。

  • 双端队列是队列,但它们支持两端的元素插入和删除。

Java队列类图

Java Queue接口扩展了Collection接口。
Collection接口扩展了Iterable接口。
一些常用的Queue实现类是LinkedList,PriorityQueue,ArrayBlockingQueue,DelayQueue,LinkedBlockingQueue,PriorityBlockingQueue等。
AbstractQueue提供了Queue接口的骨架实现,以减少实现Queue的工作量。

Java队列方法

在本节中,我们将讨论一些有用且经常使用的Java Queue方法:

  • int size():获取Set中元素的数量。

  • boolean isEmpty():检查Set是否为空。

  • boolean contains(Object o):如果此Set包含指定的元素,则返回true。

  • Iterator iterator():返回对此集合中的元素进行迭代的迭代器。
    元素以不特定的顺序返回。

  • boolean removeAll(Collection c):从此集合中删除所有包含在指定集合中的元素(可选操作)。

  • boolean keepAll(Collection c):仅保留此集合中包含在指定集合中的元素(可选操作)。

  • void clear():从集合中删除所有元素。

  • E remove():检索并删除此队列的头。

  • E poll():检索并删除此队列的头部,如果此队列为空,则返回null。

  • E peek():检索但不删除此队列的头,如果此队列为空,则返回null。

  • boolean offer(E e):如果可以在不违反容量限制的情况下立即将指定的元素插入此队列。

  • E element():检索但不删除此队列的头。

  • boolean add(E e):如果可以立即将指定的元素插入此队列,而不会违反容量限制,则在成功时返回true,如果当前没有可用空间,则抛出IllegalStateException。

  • Object [] toArray():返回包含此集合中所有元素的数组。
    如果此集合保证其迭代器返回其元素的顺序,则此方法必须以相同的顺序返回元素。

Java队列基础

随着Java Queue扩展Java Collection,它还支持所有Collection接口操作。
让我们在以下示例中探索一些简单的操作:

package com.theitroad.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数组转换为Queue。

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 Array。

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 Queue支持Collection接口支持的所有操作以及更多其他操作。
它支持两种形式的几乎所有操作。

  • 如果操作失败,则一组操作将引发异常。

  • 如果操作失败,则另一组操作将返回一个特殊值。

下表简要说明了所有"队列"常用操作。

OperationThrows exceptionSpecial value
Insertadd(e)offer(e)
Removeremove()poll()
Examineelement()peek()

我们将进行每个操作,并在接下来的部分中用一些有用的示例详细讨论它们。

Java队列插入操作

在本节中,我们将通过一些有用的示例详细讨论Java队列插入操作。
如果此操作成功执行,则返回" true"值。
众所周知,Queue支持两种形式的插入操作:

  • Queue.add(e):

如果操作失败,它将引发异常。

  • Queue.offer(e):
    It returns a special value if the operation fails.

注意:-这里的特殊值可以是" false"或者" null"

队列add()操作

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"值。
否则返回"假"值。

让我们开发一个简单的示例来演示此功能。

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 Delete操作。
如果删除操作成功执行,则它返回队列的head元素。
众所周知,Queue支持两种形式的删除操作:

  • Queue.remove():

如果操作失败,它将引发异常。

  • Queue.poll():
    It returns a special value if the operation fails.

注意:-这里的特殊值可以是" false"或者" null"

队列remove()操作

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"值。
否则返回"假"值。

队列poll()操作

poll()操作用于从队列的开头删除元素。
如果成功执行删除操作,则返回队列的头元素。
否则返回"空"值。

让我们开发一个简单的示例来演示此功能。

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()方法时,它将返回空值,如上所示。

Java队列检查操作

在本节中,我们将通过一些有用的示例详细讨论Java队列检查操作。
如果此操作成功执行,它将返回队列的head元素而不将其删除。
众所周知,Queue支持两种形式的检查操作:

  • Queue.element():

如果操作失败,它将引发异常。

  • Queue.peek():
    It returns a special value if the operation fails.

注意:-这里的特殊值可以是" false"或者" null"

队列element()操作

element()操作用于从队列的开头检索元素,而不将其删除。
如果成功执行检查操作,则返回队列的head元素。
否则,它将引发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

如果我们尝试在空Queue上调用element()方法,则它将引发异常,如上所示。

队列peek()操作

peek()操作用于从队列的开头检索元素,而不将其删除。
如果成功执行检查操作,则返回队列的head元素。
否则返回空值。

让我们开发一个简单的示例来演示此功能。

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

如果我们尝试在空Queue上调用peek()方法,它将返回null值,但不会引发如上所示的异常。

Java队列类别

在Java中,我们可以找到许多Queue实现。
W可以将它们大致分为以下两种类型

  • 有界队列
  • 无限队列

有界队列是受容量限制的队列,这意味着我们需要在创建时提供队列的最大大小。
例如ArrayBlockingQueue(请参见前面的示例)。

无限制队列是不受容量限制的队列,这意味着我们不应提供队列的大小。
例如LinkedList(请参阅前面的示例)。

java.util包中可用的所有队列都是"无界队列",而java.util.concurrent包中可用的所有队列是"有界队列"。

通过其他方式,W可以将它们大致分为以下两种类型:

  • 阻塞队列
  • 非阻塞队列

实现BlockingQueue接口的所有队列都是BlockingQueue,其余的都是Non-Blocking队列。

BlockingQueues会一直阻塞直到完成工作或者超时,但Non-BlockingQueues不会阻塞。

一些队列是双端队列,一些队列是PriorityQueue。

BlockingQueue操作

除了Queue的两种操作形式外,BlockingQueue的支持另外两种形式,如下所示。

OperationThrows exceptionSpecial valueBlocksTimes out
Insertadd(e)offer(e)put(e)offer(e, time, unit)
Removeremove()poll()take()poll(time, unit)
Examineelement()peek()N/AN/A

某些操作将被阻止直到完成工作,而其他操作将被阻止直到超时。