Java队列

时间:2020-01-09 10:35:48  来源:igfitidea点击:

Java Queue接口java.util.Queue表示一种数据结构,设计为在队列末尾插入元素,并从队列开头删除元素。这类似于超市中的队列工作方式。

JavaQueue接口是Java Collection接口的子类型。它表示对象的有序序列,就像Java列表一样,但是其预期用途略有不同。因为Java Queue接口是JavaCollection接口的子类型,所以Queue接口中也提供了Collection接口中的所有方法。

Java队列实现

由于Queue是一个接口,因此我们需要实例化该接口的具体实现才能使用它。我们可以在Java Collections API的以下" Queue"实现之间进行选择:

  • java.util.LinkedList
  • java.util.PriorityQueue

LinkedList是一个非常标准的队列实现。队列中的元素内部存储在标准链表数据结构中。这样可以快速将元素插入列表的末尾(尾部),并从列表的开头(头)除去元素。

" PriorityQueue"根据其自然顺序(如果它们实现" Comparable")或者根据传递给" PriorityQueue"的" Comparator"在内部存储其元素。

以下是一些如何创建Queue实例的示例:

Queue queueA = new LinkedList();
Queue queueB = new PriorityQueue();

在大多数"队列"实现中,队列的头和尾在相反的两端。但是,可以实现" Queue"接口,以使队列的头尾在同一端。在这种情况下,我们将拥有一个堆栈。

通用队列

默认情况下,我们可以将任何"对象"放入"队列",但是从Java 5开始,Java泛型可以限制我们可以插入"队列"的对象的类型。这是一个例子:

Queue<MyObject> queue = new LinkedList<MyObject>();

现在,该"队列"只能插入" MyObject"实例。然后,我们可以访问和迭代其元素,而无需强制转换它们。外观如下:

Queue<MyObject> queue = new LinkedList<MyObject>();

MyObject myObject = queue.remove();

for(MyObject anObject : queue){
   //do someting to anObject...
}

注意,第一行不需要强制转换,并且for-each循环如何将Queue的每个元素直接强制转换为MyObject实例。这是可能的,因为队列是使用MyObject作为通用类型创建的。

如果知道的话,总是为Queue指定通用类型是一种好习惯。这有助于Java编译器检查类型,编写更紧凑的代码,并帮助代码的下一个阅读者了解此Queue包含哪些对象类型。有关Java泛型的更多信息,请参见Java泛型教程。

将元素添加到队列

Java Queue接口包含两种方法,可用于将元素添加到Queue中。这些方法是add()方法和offer()方法。这两种方法将元素添加到队列的末尾。 add()和offer()方法在队列已满的情况下的行为方式有所不同,因此无法添加更多元素。在这种情况下,add()方法会引发异常,而offer()方法只会返回" false"。这是两个通过其add()offer()方法向Java Queue添加元素的示例:

Queue<String> queue = new LinkedList<>();

queue.add("element 1");

queue.offer("element 2");

从队列中取出元素

要从Java队列中获取元素,可以调用其poll()或者remove()方法。 poll()和remove()都删除队列中的第一个元素。如果队列为空,它们的行为方式有所不同。如果Queue为空,则poll()方法返回null。如果Queue为空,则remove()方法将引发异常。以下是两个使用Java队列中的poll()remove()方法获取元素的示例:

Queue<String> queue = new LinkedList<>();

queue.add("element 1");
queue.add("element 2");

String element1 = queue.poll();

String element2 = queue.remove();

poll()的调用将删除Queue的第一个元素,这是第一个添加了" element 1"的Java String实例。

rmove()的调用将删除Queue的第二个元素,该元素在第一个poll()调用之后现在是String实例添加的" element 2"。

窥视队列

我们可以窥视"队列"顶部的元素,而无需将该元素从"队列"中取出。这是通过Queue的element()或者peek()方法完成的。

element()方法返回Queue中的第一个元素。如果Queue为空,则element()方法抛出NoSuchElementException。这是一个使用element()方法窥视Java Queue的第一个元素的示例:

Queue<String> queue = new LinkedList<>();

queue.add("element 1");
queue.add("element 2");
queue.add("element 3");

String firstElement = queue.element();

运行此Java代码后," firstElement"变量将包含值" element 1",这是" Queue"中的第一个元素。

peek()与element()方法类似,但是如果Queue为空则不会抛出异常。相反,它只返回" null"。这是一个使用peek()方法来查看'Queue'的第一个元素的示例:

Queue<String> queue = new LinkedList<>();

queue.add("element 1");
queue.add("element 2");
queue.add("element 3");

String firstElement = queue.peek();

从队列中删除元素

要从JavaQueue中删除元素,可以调用remove()方法。此方法删除"队列"开头的元素。

这是从Java队列中删除元素的示例:

Queue<String> queue = new LinkedList<>();

queue.add("element 0");
queue.add("element 1");

String removedElement = queue.remove();

从队列中删除所有元素

我们可以使用它的clear()方法从Java队列中删除所有元素。 clear()方法实际上是从Collection接口继承的。这是一个通过其clear()方法从Java队列中删除所有元素的示例:

queue.clear();

获取队列大小

我们可以通过Java Queue的size()方法读取存储其中的元素数量。这是一个通过它的size()方法获取Java队列大小的示例:

Queue<String> queue = new LinkedList<>();

queue.add("element 1");
queue.add("element 2");
queue.add("element 3");

int size = queue.size();

运行此代码后,size变量应包含值3,因为在调用size()时队列包含3个元素。

检查队列是否包含元素

我们可以通过其" contains()"方法检查Java队列是否包含某个元素。如果Queue包含给定的元素,则contains()方法将返回true,否则返回false。实际上,contains()方法是从Collection接口继承的,但实际上并不重要。这是检查Java队列是否包含给定元素的两个示例:

Queue<String> queue = new LinkedList<>();

queue.add("Mazda");

boolean containsMazda = queue.contains("Mazda");
boolean containsHonda = queue.contains("Honda");

运行此代码后,containsMazda变量将具有值'true',而containsHonda变量将具有值'false',因为队列包含" Mazda"字符串元素,但不包含" Honda"字符串元素。

迭代队列中的所有元素

我们还可以迭代Java队列的所有元素,而不必一次处理一个。这是一个迭代Java队列中所有元素的示例:

Queue<String> queue = new LinkedList<>();

queue.add("element 0");
queue.add("element 1");
queue.add("element 2");

//access via Iterator
Iterator<String> iterator = queue.iterator();
while(iterator.hasNext(){
  String element = iterator.next();
}

//access via new for-loop
for(String element : queue) {
    //do something with each element
}

当通过其"迭代器"或者通过for-each循环(也使用幕后的迭代器)迭代"队列"时,元素迭代的顺序取决于队列的实现。