java Queue 详解

Java Queue 详解

Queue 是 Java 集合框架中用于实现 队列 数据结构的接口,位于 java.util 包中。队列是一种 先进先出(FIFO) 的数据结构,元素按照插入的顺序依次出队。


1. Queue 的基本特性

  1. FIFO(First-In-First-Out)

    • 队列中的第一个元素是最先被处理的。
    • 特殊实现(如 Deque)可以支持双向队列操作。
  2. 队列操作

    • 插入元素:add() / offer()
    • 访问元素(不移除):element() / peek()
    • 移除元素:remove() / poll()
  3. 接口定义
    Queue 是一个接口,继承自 java.util.Collection

  4. 实现类

    • LinkedList(常用)
    • PriorityQueue
    • ArrayDeque
    • ConcurrentLinkedQueue(线程安全)

2. Queue 的方法

Queue 接口提供了以下主要方法:

方法描述
add(E e)将指定元素插入队列,如果队列已满,则抛出异常。
offer(E e)将指定元素插入队列,如果队列已满,则返回 false
remove()移除并返回队列头部的元素,如果队列为空,则抛出异常。
poll()移除并返回队列头部的元素,如果队列为空,则返回 null
element()返回队列头部的元素(不移除),如果队列为空,则抛出异常。
peek()返回队列头部的元素(不移除),如果队列为空,则返回 null

方法对比

方法类型抛出异常返回特殊值
插入add()offer()
移除remove()poll()
访问(不移除)element()peek()

3. Queue 的实现类

3.1 LinkedList

  • LinkedListQueue 的常用实现之一,底层基于链表实现。
  • 它既可以用作队列(FIFO),也可以用作双向队列(Deque)。
示例:
import java.util.LinkedList;
import java.util.Queue;

public class LinkedListQueue {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();

        // 添加元素
        queue.add("A");
        queue.add("B");
        queue.add("C");

        // 访问头部元素
        System.out.println("Head: " + queue.peek()); // 输出:A

        // 移除元素
        System.out.println("Removed: " + queue.poll()); // 输出:A

        // 遍历队列
        for (String item : queue) {
            System.out.println(item); // 输出:B, C
        }
    }
}

3.2 PriorityQueue

  • 基于 堆(Heap) 实现的队列,元素按照自然顺序或自定义顺序排序。
  • 特点
    • 不保证 FIFO 顺序,优先级高的元素先出队。
    • 适合实现优先级任务调度。
示例:
import java.util.PriorityQueue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        // 添加元素
        pq.add(5);
        pq.add(2);
        pq.add(8);
        pq.add(1);

        // 按优先级移除元素
        while (!pq.isEmpty()) {
            System.out.println(pq.poll()); // 输出:1, 2, 5, 8
        }
    }
}

注意PriorityQueue 不支持 null 元素。


3.3 ArrayDeque

  • 基于 动态数组 实现的双端队列(Deque)。
  • 特点
    • LinkedList 更高效(无额外的链表节点开销)。
    • 可以用作栈(LIFO)或队列(FIFO)。
示例:
import java.util.ArrayDeque;
import java.util.Queue;

public class ArrayDequeExample {
    public static void main(String[] args) {
        Queue<String> queue = new ArrayDeque<>();

        // 添加元素
        queue.offer("X");
        queue.offer("Y");
        queue.offer("Z");

        // 访问头部元素
        System.out.println("Head: " + queue.peek()); // 输出:X

        // 移除元素
        System.out.println("Removed: " + queue.poll()); // 输出:X
    }
}

3.4 ConcurrentLinkedQueue

  • 是一个线程安全的非阻塞队列,基于 CAS(Compare-And-Swap) 实现。
  • 适用场景
    • 适用于高并发场景下的无界队列。
示例:
import java.util.concurrent.ConcurrentLinkedQueue;

public class ConcurrentQueueExample {
    public static void main(String[] args) {
        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

        // 添加元素
        queue.offer("P");
        queue.offer("Q");
        queue.offer("R");

        // 访问头部元素
        System.out.println("Head: " + queue.peek()); // 输出:P

        // 移除元素
        System.out.println("Removed: " + queue.poll()); // 输出:P
    }
}

4. 特殊队列

4.1 阻塞队列(BlockingQueue)

  • 提供阻塞操作的队列接口,位于 java.util.concurrent 包中。
  • 主要实现类
    • ArrayBlockingQueue:基于数组的有界阻塞队列。
    • LinkedBlockingQueue:基于链表的阻塞队列。
    • PriorityBlockingQueue:支持优先级排序的阻塞队列。
    • SynchronousQueue:一个没有存储能力的队列,直接在生产者和消费者之间传递数据。
示例:
import java.util.concurrent.ArrayBlockingQueue;

public class BlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(3);

        // 添加元素
        queue.put("1");
        queue.put("2");
        queue.put("3");

        // 移除元素
        System.out.println(queue.take()); // 输出:1
    }
}

特点

  • 当队列满时,插入操作会阻塞。
  • 当队列空时,删除操作会阻塞。

4.2 双端队列(Deque)

  • Queue 的子接口,支持从两端插入和删除元素。
  • 常见实现:
    • ArrayDeque
    • LinkedList
示例:
import java.util.Deque;
import java.util.LinkedList;

public class DequeExample {
    public static void main(String[] args) {
        Deque<String> deque = new LinkedList<>();

        // 添加元素
        deque.addFirst("A");
        deque.addLast("B");

        // 访问头尾元素
        System.out.println("First: " + deque.getFirst()); // 输出:A
        System.out.println("Last: " + deque.getLast());   // 输出:B

        // 移除元素
        deque.removeFirst();
        System.out.println("After removing first: " + deque);
    }
}

5. Queue 的常见用例

5.1 任务调度

  • 使用 PriorityQueueBlockingQueue 实现任务调度。

5.2 消息队列

  • 使用 ConcurrentLinkedQueueBlockingQueue 实现线程间通信。

5.3 树/图的广度优先搜索(BFS)

  • 使用 Queue 存储待访问的节点。
示例:
import java.util.LinkedList;
import java.util.Queue;

public class BFSExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();

        // 初始化队列
        queue.offer(1);

        while (!queue.isEmpty()) {
            int node = queue.poll();
            System.out.println("Visited node: " + node);
            // 模拟添加邻居节点
            if (node < 3) {
                queue.offer(node + 1);
            }
        }
    }
}

输出

Visited node: 1
Visited node: 2
Visited node: 3

6. 总结

常用实现类对比

实现类特点适用场景
LinkedList基于链表,支持双端队列操作;性能适中。一般队列操作或双向队列。
PriorityQueue元素按优先级排序,不保证 FIFO 顺序。优先级任务调度。
ArrayDeque高效实现队列和栈;比 LinkedList 更节省内存。双端队列或栈的实现。
ConcurrentLinkedQueue线程安全的无界队列,适用于高并发场景。多线程环境下的队列操作。
BlockingQueue提供阻塞操作,用于线程间通信。生产者-消费者模式。

选择 Queue 实现时,应根据具体需求(如是否需要优先级、线程安全等)选择合适的实现类。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921014.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络(14)ip地址超详解

先看图&#xff1a; 注意看第三列蓝色标注的点不会改变&#xff0c;A类地址第一个比特只会是0&#xff0c;B类是10&#xff0c;C类是110&#xff0c;D类是1110&#xff0c;E类是1111. IPv4地址根据其用途和网络规模的不同&#xff0c;分为五个主要类别&#xff08;A、B、C、D、…

shell脚本启动springboot项目

nohup java -jar springboot.jar > springboot.log 2>&1 & 表示日志输出重定向到springboot.log日志文件, 而原本的日志继续输出到 项目同级的log文件夹下, 所以这个重定向没必要. 我们没必要要2分日志 #!/bin/bash# 获取springboot项目的进程ID PID$(ps -e…

51c大模型~合集76

我自己的原文哦~ https://blog.51cto.com/whaosoft/12617524 #诺奖得主哈萨比斯新作登Nature&#xff0c;AlphaQubit解码出更可靠量子计算机 谷歌「Alpha」家族又壮大了&#xff0c;这次瞄准了量子计算领域。 今天凌晨&#xff0c;新晋诺贝尔化学奖得主、DeepMind 创始人哈萨…

FileProvider高版本使用,跨进程传输文件

高版本的android对文件权限的管控抓的很严格,理论上两个应用之间的文件传递现在都应该是用FileProvider去实现,这篇博客来一起了解下它的实现原理。 首先我们要明确一点,FileProvider就是一个ContentProvider,所以需要在AndroidManifest.xml里面对它进行声明: <provideran…

【Java】二叉树:数据海洋中灯塔式结构探秘(上)

个人主页 &#x1f339;&#xff1a;喜欢做梦 二叉树中有一个树&#xff0c;我们可以猜到他和树有关&#xff0c;那我们先了解一下什么是树&#xff0c;在来了解一下二叉树 一&#x1f35d;、树型结构 1&#x1f368;.什么是树型结构&#xff1f; 树是一种非线性的数据结构&…

网口输出的加速度传感器

一、功能概述 1.1 设备简介 本模块为了对电机、风机、水泵等旋转设备进行预测性运维而开发&#xff0c;只需一个模块&#xff0c; 就可以采集旋转设备的 3 路振动信号&#xff08;XYZ 轴&#xff09;和一路温度信号&#xff0c;防护等级 IP67 &#xff0c;能够 适应恶劣的工业…

力扣面试经典 150(上)

文章目录 数组/字符串1. 合并两个有序数组2. 移除元素3. 删除有序数组中的重复项4. 删除有序数组的重复项II5. 多数元素6. 轮转数组7. 买卖股票的最佳时机8. 买卖股票的最佳时机II9. 跳跃游戏10. 跳跃游戏II11. H 指数12. O(1)时间插入、删除和获取随机元素13. 除自身以外数组的…

浅谈 proxy

应用场景 Vue2采用的defineProperty去实现数据绑定&#xff0c;Vue3则改为Proxy&#xff0c;遇到了什么问题&#xff1f; - 在Vue2中不能检测数组和对象的变化 1. 无法检测 对象property 的添加或移除 var vm new Vue({data:{a:1} })// vm.a 是响应式的vm.b 2 // vm.b 是…

P4-1【应用数组进行程序设计】第一节——知识要点:一维数组

视频&#xff1a; P4-1【应用数组进行程序设计】第一节——知识要点&#xff1a;一维数组 项目四 应用数组进行程序设计 任务一&#xff1a;冒泡排序 知识要点&#xff1a;一维数组 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 用冒泡法对任意输入…

【数据库入门】关系型数据库入门及SQL语句的编写

1.数据库的类型&#xff1a; 数据库分为网状数据库&#xff0c;层次数据库&#xff0c;关系型数据库和非关系型数据库四种。 目前市场上比较主流的是&#xff1a;关系型数据库和非关系型数据库。 关系型数据库使用结构化查询语句&#xff08;SQL&#xff09;对关系型数据库进行…

day07(单片机高级)继电器模块绘制

目录 继电器模块绘制 原理图 布局 添加板框 布线 按tab修改线宽度 布线换层 泪滴 铺铜 铺铜的作用 铺铜的使用规范 添加丝印 步骤总结 继电器模块绘制 到淘宝找一个继电器模块 继电器模块的使用&#xff08;超详细&#xff09;_继电器模块工作原理-CSDN博客文章浏览阅读4.8w次&…

1+X应急响应(网络)病毒与木马的处置:

病毒与木马的处置&#xff1a; 病毒与木马的简介&#xff1a; 病毒和木马的排查与恢复&#xff1a;

【电路笔记 TMS320F28335DSP】时钟+看门狗+相关寄存器(功能模块使能、时钟频率配置、看门狗配置)

时钟源和主时钟&#xff08;SYSCLKOUT&#xff09; 外部晶振&#xff1a;通常使用外部晶振&#xff08;如 20 MHz&#xff09;作为主要时钟源。内部振荡器&#xff1a;还可以选择内部振荡器&#xff08;INTOSC1 和 INTOSC2&#xff09;&#xff0c;适合无需高精度外部时钟的应…

CCE-基础

背景&#xff1a; 虚拟化产生解决物理机资源浪费问题&#xff0c;云计算出现实现虚拟化资源调度和管理&#xff0c;容器出现继续压榨虚拟化技术产生的资源浪费&#xff0c;用命名空间隔离&#xff08;namespace&#xff09; 灰度升级&#xff08;升级中不影响业务&#xff09…

基于LLama_factory的Qwen2.5大模型的微调笔记

Qwen2.5大模型微调记录 LLama-facrotyQwen2.5 模型下载。huggingface 下载方式Modelscope 下载方式 数据集准备模型微调模型训练模型验证及推理模型导出 部署推理vllm 推理Sglang 推理 LLama-facroty 根据git上步骤安装即可&#xff0c;要求的软硬件都装上。 llama-factory运行…

提取图片高频信息

提取图片高频信息 示例-输入&#xff1a; 示例-输出&#xff1a; 代码实现&#xff1a; import cv2 import numpy as npdef edge_calc(image):src cv2.GaussianBlur(image, (3, 3), 0)ddepth cv2.CV_16Sgray cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)grad_x cv2.Scharr(g…

移动充储机器人“小奥”的多场景应用(上)

一、高速公路服务区应用 在高速公路服务区&#xff0c;新能源汽车的充电需求得到“小奥”机器人的及时响应。该机器人配备有储能电池和自动驾驶技术&#xff0c;能够迅速定位至指定充电点&#xff0c;为待充电的新能源汽车提供服务。得益于“小奥”的机动性&#xff0c;其服务…

怎么只提取视频中的声音?从视频中提取纯音频技巧

在数字媒体的广泛应用中&#xff0c;提取视频中的声音已成为一项常见且重要的操作。无论是为了学习、娱乐、创作还是法律用途&#xff0c;提取声音都能为我们带来诸多便利。怎么只提取视频中的声音&#xff1f;本文将详细介绍提取声音的原因、工具、方法以及注意事项。 一、为什…

Windows环境GeoServer打包Docker极速入门

目录 1.前言2.安装Docker3.准备Dockerfile4.拉取linux环境5.打包镜像6.数据挂载6.测试数据挂载7.总结 1.前言 在 Windows 环境下将 GeoServer 打包为 Docker&#xff0c;可以实现跨平台一致性、简化环境配置、快速部署与恢复&#xff0c;同时便于扩展集成和版本管理&#xff0c…

《Vue零基础入门教程》第四课: 应用实例

往期内容 《Vue零基础入门教程》第一课&#xff1a;Vue简介 《Vue零基础入门教程》第二课&#xff1a;搭建开发环境 《Vue零基础入门教程》第三课&#xff1a;起步案例 参考官方文档 https://cn.vuejs.org/api/application#create-app 示例 const {createApp} Vue// 通…