Java中的队列接口

Java中的队列接口

队列接口位于java.util包中,扩展了Collection接口,用于按照FIFO(先进先出)顺序保持即将处理的元素。 它是一个带顺序的对象列表,其使用限制为在列表末尾插入元素并从列表开始删除元素,即遵循先进先出原则。

Java中的队列接口

作为一个接口,队列需要一个具体类进行声明,最常见的类是Java中的PriorityQueue和LinkedList。请注意,这些实现都不是线程安全的。如果需要线程安全的实现,则PriorityBlockingQueue是一种替代实现。

声明: 队列接口声明如下:

public interface Queue extends Collection 

创建队列对象: 由于队列是一个接口,因此无法创建队列类型的对象。我们总是需要一个扩展此列表的类来创建对象。而且,在Java 1.5引入泛型后,可以限制可以存储在队列中的对象类型。可以定义此类型安全队列如下:

// Obj是要存储在队列中的对象的类型
Queue<Obj> queue = new PriorityQueue<Obj>(); 

在Java中,队列接口是Collection接口的子类型,表示按特定顺序排列的元素集合。它遵循先进先出(FIFO)原则,这意味着元素按照它们添加到队列中的顺序检索。

队列接口为在队列中添加、删除和检查元素提供了多种方法。以下是一些最常用的方法:

add(element):将元素添加到队列的末尾。如果队列已满,则会抛出异常。

offer(element):将元素添加到队列的末尾。如果队列已满,则返回false。

remove():删除并返回队列前面的元素。如果队列为空,则会抛出异常。

poll():删除并返回队列前面的元素。如果队列为空,则返回null。

element():返回队列前面的元素但不将其删除。如果队列为空,则会抛出异常。

peek():返回队列前面的元素但不将其删除。如果队列为空,则返回null。

Java中的LinkedList、ArrayDeque和PriorityQueue等类实现了队列接口。这些类提供了队列接口的不同实现,具有不同的性能特征和功能。

总体而言,队列接口是管理按特定顺序排列的元素集合的有用工具,并在许多不同的应用和行业中得到广泛应用。

示例:

import java.util.LinkedList;
import java.util.Queue;
 
public class QueueExample {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
 
        // 向队列中添加元素
        queue.add("apple");
        queue.add("banana");
        queue.add("cherry");
 
        // 打印队列
        System.out.println("队列: " + queue);
 
        // 移除队列最前面的元素
        String front = queue.remove();
        System.out.println("移除的元素: " + front);
 
        // 打印更新后的队列
        System.out.println("移除一个元素后的队列: " + queue);
 
        // 向队列中添加另一个元素
        queue.add("date");
 
        // 查看队列最前面的元素
        String peeked = queue.peek();
        System.out.println("查看的元素: " + peeked);
 
        // 打印更新后的队列
        System.out.println("查看最前面的元素后的队列: " + queue);
    }
}

输出

队列: [apple, banana, cherry]
移除的元素: apple
移除一个元素后的队列: [banana, cherry]
查看的元素: banana
查看最前面的元素后的队列: [banana, cherry, date]

例子: 队列

// Java程序演示队列
 
import java.util.LinkedList;
import java.util.Queue;
 
public class QueueExample {
 
    public static void main(String[] args)
    {
        Queue<Integer> q
            = new LinkedList<>();
 
        // 将元素{0, 1, 2, 3, 4}添加到队列中
        for (int i = 0; i < 5; i++)
            q.add(i);
 
        // 显示队列的内容
        System.out.println("队列元素 "
                           + q);
 
        // 移除队列的头部元素
        int removedele = q.remove();
        System.out.println("移除的元素-"
                           + removedele);
 
        System.out.println(q);
 
        // 查看队列的头部元素
        int head = q.peek();
        System.out.println("队列的头部元素-"
                           + head);
 
        // 可以使用Collection接口的其他方法,
        // 如size和contains
        // 与此实现一起使用。
        int size = q.size();
        System.out.println("队列的大小-"
                           + size);
    }
}

输出:

队列元素 [0, 1, 2, 3, 4]
移除的元素-0
[1, 2, 3, 4]
队列的头部元素-1
队列的大小-4

队列接口上的操作

让我们看一下如何使用PriorityQueue类执行队列上使用频率较高的操作。

1. 添加元素: 为了在队列中添加元素,我们可以使用add()方法。 PriorityQueue中不保留插入顺序。元素按默认的升序优先级存储。

例子

// Java程序添加元素到队列中
 
import java.util.*;
 
public class GFG {
 
    public static void main(String args[])
    {
        Queue<String> pq = new PriorityQueue<>();
 
        pq.add("Geeks");
        pq.add("For");
        pq.add("Geeks");
 
        System.out.println(pq);
    }
}

输出:

[For, Geeks, Geeks]

2. 移除元素: 为了从队列中移除元素,我们可以使用remove()方法。如果存在多个这样的对象,则将删除第一个对象。除此之外,还可以使用poll()方法从头部移除并返回它。

例子

// Java程序来移除元素
// 从队列
 
import java.util.*;
 
public class GFG {
 
    public static void main(String args[])
    {
        Queue<String> pq = new PriorityQueue<>();
 
        pq.add("Geeks");
        pq.add("For");
        pq.add("Geeks");
 
        System.out.println("初始队列 " + pq);
 
        pq.remove("Geeks");
 
        System.out.println("移除后 " + pq);
 
        System.out.println("Poll Method " + pq.poll());
 
        System.out.println("最终队列 " + pq);
    }
}

输出:

初始队列 [For, Geeks, Geeks]
移除后 [For, Geeks]
Poll Method For
最终队列 [Geeks]

3. 遍历队列: 遍历队列有多种方法。最著名的方法是将队列转换为数组并使用for循环遍历。但是,队列也有一个内置迭代器,可以用于遍历队列。

例子

// Java程序来迭代元素
// 到队列
 
import java.util.*;
 
public class GFG {
 
    public static void main(String args[])
    {
        Queue<String> pq = new PriorityQueue<>();
 
        pq.add("Geeks");
        pq.add("For");
        pq.add("Geeks");
 
        Iterator iterator = pq.iterator();
 
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
    }
}

输出:

For Geeks Geeks

队列的特征: 队列的特征如下:

  • 队列用于在队列末尾插入元素并从队列开头删除元素。它遵循FIFO概念。
  • Java队列支持Collection接口的所有方法,包括插入,删除等。
  • LinkedList,ArrayBlockingQueue和PriorityQueue是最常用的实现。
  • 如果在BlockingQueues上执行任何空操作,则引发NullPointerException。
  • java.util包中可用的队列是无界队列。
  • Java.util.concurrent包中可用的队列是有界队列。
  • 除了Deques以外的所有队列都支持在队列的尾部和头部插入和删除元素。Deques支持在两端插入和删除元素。

实现队列接口的类:

1. PriorityQueue: PriorityQueue类是在集合框架中实现的,它为我们提供了根据优先级处理对象的方法。已知队列遵循先进先出算法,但有时需要根据优先级处理队列的元素,这就是PriorityQueue发挥作用的时候。让我们看看如何使用这个类创建一个队列对象。

例子

// Java program to demonstrate the
// creation of queue object using the
// PriorityBlockingQueue class
 
import java.util.concurrent.*;
 
class GfG {
 
    public static void main(String args[])
    {
        // Creating empty
        // PriorityBlockingQueue
        Queue<Integer> pbq
            = new PriorityBlockingQueue<Integer>();
 
        // Adding items to the pbq
        // using add()
        pbq.add(10);
        pbq.add(20);
        pbq.add(15);
 
        // Printing the top element of
        // the PriorityBlockingQueue
        System.out.println(pbq.peek());
 
        // Printing the top element and removing it
        // from the PriorityBlockingQueue container
        System.out.println(pbq.poll());
 
        // Printing the top element again
        System.out.println(pbq.peek());
    }
}

输出:

10
10
15

2. LinkedList: LinkedList是在集合框架中实现链表数据结构的类。它是一种线性数据结构,元素不存储在连续的位置,并且每个元素都是具有数据部分和地址部分的单独对象。元素使用指针和地址链接。每个元素称为节点。由于插入和删除的动态性和易于性,它们比数组或队列更受青睐。让我们看看如何使用这个类创建一个队列对象。

示例

// Java program to demonstrate the
// creation of queue object using the
// LinkedList class
 
import java.util.*;
 
class GfG {
 
    public static void main(String args[])
    {
        // Creating empty LinkedList
        Queue<Integer> ll
            = new LinkedList<Integer>();
 
        // Adding items to the ll
        // using add()
        ll.add(10);
        ll.add(20);
        ll.add(15);
 
        // Printing the top element of
        // the LinkedList
        System.out.println(ll.peek());
 
        // Printing the top element and removing it
        // from the LinkedList container
        System.out.println(ll.poll());
 
        // Printing the top element again
        System.out.println(ll.peek());
    }
}

输出:

10
10
20

3. PriorityBlockingQueue: 请注意,PriorityQueue和LinkedList这两个实现都不是线程安全的。如果需要线程安全实现,则PriorityBlockingQueue是一种替代实现。PriorityBlockingQueue是一个无界阻塞队列,使用与PriorityQueue类相同的排序规则,并提供阻塞检索操作。
由于它是无界的,添加元素有时可能会因资源耗尽而失败,从而导致OutOfMemoryError。让我们看看如何使用这个类创建一个队列对象。

示例

// Java程序示例展示了使用PriorityBlockingQueue类创建队列对象
 
import java.util.concurrent.PriorityBlockingQueue;
import java.util.*;
 
class GfG {
    public static void main(String args[])
    {
        // 创建空的优先阻塞队列
        Queue<Integer> pbq
            = new PriorityBlockingQueue<Integer>();
 
        // 使用add()向pbq添加项目
        pbq.add(10);
        pbq.add(20);
        pbq.add(15);
 
        // 打印PriorityBlockingQueue的顶部元素
        System.out.println(pbq.peek());
 
        // 打印PriorityBlockingQueue的顶部元素并将其删除
        System.out.println(pbq.poll());
 
        // 再次打印PriorityBlockingQueue的顶部元素
        System.out.println(pbq.peek());
    }
}

输出:

10
10
15

Queue接口的方法

队列接口继承了集合接口中的所有方法,同时实现以下方法:

方法 描述
add(int index, element) 该方法用于在队列的特定索引处添加一个元素。当传递单个参数时,它只是将元素添加到队列的末尾。
addAll(int index, Collection collection) 该方法用于将给定集合中的所有元素添加到队列中。当传递单个参数时,它将给定集合中的所有元素添加到队列的末尾。
size() 该方法用于返回队列的大小。
clear() 该方法用于删除队列中的所有元素。然而,所创建的队列的引用仍然存储。
remove() 该方法用于从队列的前面移除元素。
remove(int index) 该方法用于从指定的索引处删除一个元素。它将后续元素(如果有)向左移动并将它们的索引减少1。
remove(element) 该方法用于删除并返回队列中给定元素的第一个出现位置。
get(int index) 该方法返回指定索引处的元素。
set(int index, element) 该方法用新元素替换给定索引处的元素。此函数返回刚替换为新元素的元素。
indexOf(element) 该方法返回给定元素的第一个出现位置或-1(如果队列中不存在元素)。
lastIndexOf(element) 该方法返回给定元素的最后一个出现位置或-1(如果队列中不存在元素)。
equals(element) 该方法用于将给定元素与队列的元素进行比较。
hashCode() 该方法用于返回给定队列的哈希码值。
isEmpty() 该方法用于检查队列是否为空。如果队列为空,则返回true,否则返回false。
contains(element) 该方法用于检查队列是否包含给定元素。如果队列包含元素,则返回true。
containsAll(Collection collection) 该方法用于检查队列是否包含所有集合中的元素。
sort(Comparator comp) 该方法用于根据给定比较器对队列的元素进行排序。
boolean add(object) 该方法用于将指定元素插入队列并在成功时返回true。
boolean offer(object) 该方法用于将指定元素插入队列。
Object poll() 该方法用于检索并删除队列的头部,如果队列为空,则返回null。
Object element() 该方法用于检索队列的头部,但不删除它。
Object peek() 该方法用于检索队列的头部,但不删除它。如果队列为空,则返回null。

Java中使用队列接口的优点:

次序保存 :队列接口提供了一种按照先进先出(FIFO)原则以特定顺序存储和检索元素的方法。

灵活性 :队列接口是Collection接口的子类型,这意味着它可与许多不同的数据结构和算法一起使用,具体取决于应用程序的要求。

线程安全 :队列接口的某些实现,如java.util.concurrent.ConcurrentLinkedQueue类,是线程安全的,这意味着它们可以被多个线程同时访问而不会导致冲突。

性能 :队列接口提供了有效的实现以添加、删除和检查元素,使其成为管理元素集合的有用工具,特别适用于性能关键应用程序。

Java中使用队列接口的缺点:

功能有限: 队列接口专门设计用于管理特定顺序的元素集合,这意味着它可能不适用于更复杂的数据结构或算法。

限制大小: 队列接口的某些实现,如ArrayDeque类,具有固定的大小,这意味着它们不能超出一定数量的元素。

内存使用: 根据具体实现,队列接口可能需要比其他数据结构更多的内存,尤其是如果它需要存储有关元素顺序的其他信息。

复杂性: 队列接口对于新手程序员来说可能难以使用和理解,特别是如果他们不熟悉数据结构和算法的原理。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程