Java Queue接口及其常用实现类分析

简介: Java Queue接口及其常用实现类分析

Java集合框架中,Queue接口代表了一个队列,它是一种特殊的线性表,只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作。队列是一种先进先出(FIFO)的数据结构,即最先插入的元素将最先被删除。Java中的Queue接口提供了多种方法来操作队列中的元素,并且有多种实现类来满足不同的使用场景。


一、Queue接口的主要方法


  • add(E e): 将指定的元素插入此队列(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException
  • offer(E e): 将指定的元素插入此队列(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false
  • remove(): 检索并删除此队列的头,如果此队列为空,则抛出 NoSuchElementException
  • poll(): 检索并删除此队列的头,或返回 null 如果此队列为空。
  • element(): 检索但不删除此队列的头,如果此队列为空,则抛出 NoSuchElementException
  • peek(): 检索但不删除此队列的头,或返回 null 如果此队列为空。


二、常用实现类


  1. LinkedList
    LinkedList类实现了Queue接口,因此它可以作为队列使用。由于其内部使用双向链表实现,所以插入和删除操作都具有较高的效率。
  2. PriorityQueue
    PriorityQueue是一个基于优先级堆的无界队列。它的头部是按指定排序方式确定的最小元素。如果多个元素都是最小值,则任何一个都可能被找到。
  3. ArrayDeque
    ArrayDeque是一个双端队列,实现了Queue接口,也可以当作栈来使用。它通常比LinkedList提供更高的性能,是并发编程中首选的队列实现之一。
  4. ConcurrentLinkedQueue
    ConcurrentLinkedQueue是一个适用于多线程编程的线程安全队列,它使用高效的非阻塞算法来实现并发访问。
  5. SynchronousQueue
    SynchronousQueue是一个没有存储空间的阻塞队列,它每个插入操作必须等待一个相应的删除操作,反之亦然。


三、示例代码


下面是一些使用不同队列实现类的示例代码:

import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.ArrayDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.SynchronousQueue;
public class QueueExample {
    public static void main(String[] args) {
        // 使用LinkedList作为队列
        Queue<String> linkedListQueue = new LinkedList<>();
        linkedListQueue.offer("A");
        linkedListQueue.offer("B");
        System.out.println(linkedListQueue.poll()); // 输出 A
        // 使用PriorityQueue作为优先队列
        Queue<Integer> priorityQueue = new PriorityQueue<>();
        priorityQueue.offer(3);
        priorityQueue.offer(1); // 小的数字有更高的优先级
        System.out.println(priorityQueue.poll()); // 输出 1
        // 使用ArrayDeque作为双端队列(也可以作为栈使用)
        Queue<Integer> arrayDeque = new ArrayDeque<>();
        arrayDeque.offer(1);
        arrayDeque.offer(2); // 在尾部添加元素
        System.out.println(arrayDeque.poll()); // 输出 1
        // 使用ConcurrentLinkedQueue作为线程安全队列
        Queue<String> concurrentQueue = new ConcurrentLinkedQueue<>();
        concurrentQueue.offer("Thread-Safe"); // 在并发环境中安全地添加元素
        System.out.println(concurrentQueue.poll()); // 输出 Thread-Safe
        // 使用SynchronousQueue作为同步队列的示例(需要额外的线程来消费)
        // 这里只是演示如何创建它,实际上你会在两个线程中使用它来实现生产者-消费者模式。
        Queue<Integer> synchronousQueue = new SynchronousQueue<>();
        // synchronousQueue.offer(1); // 这会阻塞,因为没有消费者在等待接收数据。
    }
}

注意:在上面的代码中,SynchronousQueue的示例并没有实际执行offer()方法,因为这会立即阻塞当前线程,直到有另一个线程调用poll()或相应的删除方法来接收这个元素。在实际使用中,你会看到这种队列与生产者-消费者模式一起使用,其中生产者和消费者在不同的线程中运行。

Java Queue接口及其常用实现类分析

在Java集合框架中,Queue接口代表了一个队列,它是一种特殊的线性表,只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作。队列是一种先进先出(FIFO)的数据结构,即最先插入的元素将最先被删除。Java中的Queue接口提供了多种方法来操作队列中的元素,并且有多种实现类来满足不同的使用场景。

一、Queue接口的主要方法

  • add(E e): 将指定的元素插入此队列(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException
  • offer(E e): 将指定的元素插入此队列(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false
  • remove(): 检索并删除此队列的头,如果此队列为空,则抛出 NoSuchElementException
  • poll(): 检索并删除此队列的头,或返回 null 如果此队列为空。
  • element(): 检索但不删除此队列的头,如果此队列为空,则抛出 NoSuchElementException
  • peek(): 检索但不删除此队列的头,或返回 null 如果此队列为空。


二、常用实现类


  1. LinkedList
    LinkedList类实现了Queue接口,因此它可以作为队列使用。由于其内部使用双向链表实现,所以插入和删除操作都具有较高的效率。
  2. PriorityQueue
    PriorityQueue是一个基于优先级堆的无界队列。它的头部是按指定排序方式确定的最小元素。如果多个元素都是最小值,则任何一个都可能被找到。
  3. ArrayDeque
    ArrayDeque是一个双端队列,实现了Queue接口,也可以当作栈来使用。它通常比LinkedList提供更高的性能,是并发编程中首选的队列实现之一。
  4. ConcurrentLinkedQueue
    ConcurrentLinkedQueue是一个适用于多线程编程的线程安全队列,它使用高效的非阻塞算法来实现并发访问。
  5. SynchronousQueue
    SynchronousQueue是一个没有存储空间的阻塞队列,它每个插入操作必须等待一个相应的删除操作,反之亦然。


三、示例代码


下面是一些使用不同队列实现类的示例代码:

import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.ArrayDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.SynchronousQueue;
public class QueueExample {
    public static void main(String[] args) {
        // 使用LinkedList作为队列
        Queue<String> linkedListQueue = new LinkedList<>();
        linkedListQueue.offer("A");
        linkedListQueue.offer("B");
        System.out.println(linkedListQueue.poll()); // 输出 A
        // 使用PriorityQueue作为优先队列
        Queue<Integer> priorityQueue = new PriorityQueue<>();
        priorityQueue.offer(3);
        priorityQueue.offer(1); // 小的数字有更高的优先级
        System.out.println(priorityQueue.poll()); // 输出 1
        // 使用ArrayDeque作为双端队列(也可以作为栈使用)
        Queue<Integer> arrayDeque = new ArrayDeque<>();
        arrayDeque.offer(1);
        arrayDeque.offer(2); // 在尾部添加元素
        System.out.println(arrayDeque.poll()); // 输出 1
        // 使用ConcurrentLinkedQueue作为线程安全队列
        Queue<String> concurrentQueue = new ConcurrentLinkedQueue<>();
        concurrentQueue.offer("Thread-Safe"); // 在并发环境中安全地添加元素
        System.out.println(concurrentQueue.poll()); // 输出 Thread-Safe
        // 使用SynchronousQueue作为同步队列的示例(需要额外的线程来消费)
        // 这里只是演示如何创建它,实际上你会在两个线程中使用它来实现生产者-消费者模式。
        Queue<Integer> synchronousQueue = new SynchronousQueue<>();
        // synchronousQueue.offer(1); // 这会阻塞,因为没有消费者在等待接收数据。
    }
}

注意:在上面的代码中,SynchronousQueue的示例并没有实际执行offer()方法,因为这会立即阻塞当前线程,直到有另一个线程调用poll()或相应的删除方法来接收这个元素。在实际使用中,你会看到这种队列与生产者-消费者模式一起使用,其中生产者和消费者在不同的线程中运行。

相关文章
|
3天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
28 3
|
19小时前
|
存储 安全 Java
[Java基础面试题] Map 接口相关
[Java基础面试题] Map 接口相关
|
1天前
|
安全 Java 程序员
|
1天前
|
存储 Java C++
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
8 0
|
1天前
|
Java
Java Class类
Java Class类
8 0
|
6天前
|
Java 开发者
探索 Java 的函数式接口和 Lambda 表达式
【4月更文挑战第19天】Java 中的函数式接口和 Lambda 表达式提供了简洁、灵活的编程方式。函数式接口有且仅有一个抽象方法,用于与 Lambda(一种匿名函数语法)配合,简化代码并增强可读性。Lambda 表达式的优点在于其简洁性和灵活性,常用于事件处理、过滤和排序等场景。使用时注意兼容性和变量作用域,它们能提高代码效率和可维护性。
|
7天前
|
Java
Java接口中可以定义哪些方法?
【4月更文挑战第13天】
13 0
Java接口中可以定义哪些方法?
|
8天前
|
Java 编译器
Java Character 类
4月更文挑战第13天
|
7月前
|
Java
Java接口和抽象类
Java接口和抽象类
51 0
|
1月前
|
设计模式 搜索推荐 Java
java接口和抽象类的区别,以及使用选择
java接口和抽象类的区别,以及使用选择
25 0