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()或相应的删除方法来接收这个元素。在实际使用中,你会看到这种队列与生产者-消费者模式一起使用,其中生产者和消费者在不同的线程中运行。

相关文章
|
11天前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
24 0
java基础(13)String类
|
4天前
|
Java API
Java的日期类都是怎么用的
【10月更文挑战第1天】本文介绍了 Java 中处理日期和时间的三个主要类:`java.util.Date`、`java.util.Calendar` 和 `java.time` 包下的新 API。`Date` 类用于表示精确到毫秒的瞬间,可通过时间戳创建或获取当前日期;`Calendar` 抽象类提供丰富的日期操作方法,如获取年月日及时区转换;`java.time` 包中的 `LocalDate`、`LocalTime`、`LocalDateTime` 和 `ZonedDateTime` 等类则提供了更为现代和灵活的日期时间处理方式,支持时区和复杂的时间计算。
26 14
|
7天前
|
Java 测试技术
Java接口的生产环境应用注意点
在Java生产环境中,合理使用接口对提升代码质量至关重要。设计接口时应遵循单一职责原则,采用清晰命名,并控制方法数量。默认方法应谨慎使用,避免与实现类产生冲突。通过版本化管理接口更新,确保向后兼容。实现接口时需明确行为,保持实现与接口分离,利用多态增强灵活性。关注性能影响,适当文档注释及充分测试确保接口稳定可靠。综合运用这些策略,可以显著提高系统的可扩展性和维护性。
|
7天前
|
Java
Java 接口的简化理解
Java 接口是一种强大的概念,用于定义方法签名而非具体实现,作为行为规范,强调功能而非实现细节。接口是特殊的引用类型,包含常量和方法签名。其特点包括:无实现方法体、支持多重继承、内置常量定义。通过示例展示了如何定义和实现接口,以及如何通过接口引用调用实现类的方法。接口的应用场景包括抽象化、插件架构和松耦合设计。从 Java 8 起,接口还支持默认方法和静态方法,进一步增强了其灵活性和扩展性。理解接口是 Java 编程的基础之一。
|
8天前
|
安全 Java 编译器
java访问类字段
java访问类字段
|
11天前
|
Java
java的class类
java的class类
18 5
|
8天前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
7天前
|
安全 Java 调度
Java编程时多线程操作单核服务器可以不加锁吗?
Java编程时多线程操作单核服务器可以不加锁吗?
21 2
|
11天前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
16天前
|
缓存 Java 应用服务中间件
Java虚拟线程探究与性能解析
本文主要介绍了阿里云在Java-虚拟-线程任务中的新进展和技术细节。
下一篇
无影云桌面