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

相关文章
|
8月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
355 4
|
8月前
|
IDE JavaScript Java
在Java 11中,如何处理被弃用的类或接口?
在Java 11中,如何处理被弃用的类或接口?
380 5
|
8月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
411 1
|
8月前
|
Java Go 开发工具
【Java】(9)抽象类、接口、内部的运用与作用分析,枚举类型的使用
抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类abstract static不能同时修饰一个方法。
335 1
|
8月前
|
Java Go 开发工具
【Java】(8)正则表达式的使用与常用类分享
正则表达式定义了字符串的模式。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
515 1
|
8月前
|
存储 Java 程序员
【Java】(6)全方面带你了解Java里的日期与时间内容,介绍 Calendar、GregorianCalendar、Date类
java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用当前日期和时间来初始化对象。Date( )第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
331 0
|
8月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
384 1
|
9月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
412 0
|
9月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
580 16