为何我建议你学会Queue集合

news2024/9/20 5:31:19

先赞后看,南哥助你Java进阶一大半

PriorityQueue的底层数据结构就如andrewlock.net网站提供的图一样,虽然PriorityQueue是一个平衡二叉堆,但JDK底层的实现却是:一个普普通通的二维数组!!

在这里插入图片描述

我是南哥,一个Java学习与进阶的领路人,相信对你通关面试、拿下Offer进入心心念念的公司有所帮助。

⭐⭐⭐本文收录在《Java学习/进阶/面试指南》:https://github…JavaSouth

1. Queue集合

1.1 Queue集合概述

面试官:你说说Queue集合都有什么常用类?

JDK源码对Queue集合是这么解释的,大家看看。

A collection designed for holding elements prior to processing.

专为在处理之前保存元素而设计的集合。

南哥是这么理解的,List集合用于存储常用元素、Map集合用于存储具有映射关系的元素、Set集合用于存储唯一性的元素。Queue集合呢?所有的数据结构都是为了解决业务问题而生,而Queue集合这种数据结构能够存储具有先后时间关系的元素,很适用于在业务高峰期,需要缓存当前任务的业务场景。像Kafka、RabbitMQ、RocketMQ都是队列任务这种思想。

Queue集合底层接口提供的方法很简单,一共有 6 个。

    // 添加元素。没有可用元素则简单返回false
    boolean offer(E e);
    // 添加元素。没有可用元素则抛出IllegalStateException
    boolean add(E e);
    // 移除队列的头部元素。如果此队列为空则返回null 。
    E poll();
    // 移除队列的头部元素。该方法和poll不同之处在于,如果此队列为空,则抛出异常。
    E remove();
    // 检索但不移除此队列的头部。如果此队列为空,则返回null 。
    E peek();
    // 检索但不移除此队列的头部。该方法和peek唯一不同之处在于,如果此队列为空,则抛出异常
    E element();

Queue集合常用的实现类如下,我会一一讲来。包括双端队列的两个实现类:LinkedList、ArrayDeque,优先级队列:PriorityQueue,线程安全相关的Queue实现类:LinkedBlockingQueue、ArrayBlockingQueue、ConcurrentLinkedQueue。

在这里插入图片描述

1.2 双端队列

面试官:双端队列的两个实现类知道吧?

双端队列是Queue集合的一个子接口,顾名思义相比普通队列来说,双端队列可以往前、也可以往后顺序插入元素。比如我下面给出一段队列的初始化。

        Queue<Integer> queue = new LinkedList<>();
        Deque<Integer> deque = new LinkedList<>();

        queue.add(1);
        deque.addLast(1);
        deque.addFirst(1);

同样是new LinkedList<>()来实例化队列,如果使用双端队列Deque接口,那这个队列就可以使用addFirstaddLast等双端队列特有的方法。

有南友就会问:那ArrayQueue呢?这两者都是双端队列Deque的底层实现,但底层数据结构不同,LinkedList底层数据结构是一个双向链表,看看它有前指针next、后指针prev

    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

而ArrayDeque底层数据结构是一个Object类型的数组。

    transient Object[] elements;

为什么要这么设计呢?其实这两种不同的设计就可以高效适用于不同的业务场景。双向链表实现的Deque随机查找的性能差,但插入、删除元素时性能非常出色,适用于修改操作更频繁的业务场景。

而数组实现的Deque,也就是ArrayDeque,它的插入、删除操作性能不如前者,但随机查找的性能非常出色,更适用于查询操作更频繁的业务场景。

1.3 优先级队列

面试官:优先级队列有什么作用?

优先级队列的实现类叫PriorityQueue,PriorityQueue虽然属于队列的一份子,不过它违背了队列最基本的原则:FIFO先进先出原则。它背叛了组织!

PriorityQueue的特性是它并不按常规队列一样顺序存储,而是根据元素的自然顺序进行排序,使用出队列的方法也是输出当前优先级最高的元素。例如以下代码输出的一样。

    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();
        queue.offer(6);
        queue.offer(1);
        queue.offer(3);

        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }
# 执行结果
1
3
6

但如果我们直接打印PriorityQueue的所有元素,发现他其实并不是按元素的自然顺序进行存储。

    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();
        queue.offer(6);
        queue.offer(1);
        queue.offer(3);

        System.out.println(queue);
    }
# 执行结果
[1, 6, 3]

why?其实PriorityQueue底层数据结构是一个平衡二叉堆transient Object[] queue,如果你直接打印,打印的是堆里面的存储元素。

对于PriorityQueue来说,它只保证你使用poll()操作时,返回的是队列中最小、或最大的元素。

1.4 阻塞队列

面试官:阻塞队列呢?

JDK提供的阻塞队列接口为BlockingQueue,南哥先说说BlockingQueue的子类实现之一:ArrayBlockingQueue。

阻塞队列的特别之处在于当生产者线程会往队列放入元素时,如果队列已满,则生产者线程会进入阻塞状态;而当消费者线程往队列取出元素时,如果队列空了,则消费者线程会进入阻塞状态。

但队列的状态从满变为不满,消费者线程会唤醒生产者线程继续生产;队列的状态从空变为不空,生产者线程会唤醒消费者线程继续消费。

所以ArrayBlockingQueue很适合用于实现生产者、消费者场景。大家看看这个Demo。

public class Test {
    public static void main(String[] args) {
        // 创建一个容量为 3 的ArrayBlockingQueue
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);

        // 创建并启动生产者线程
        Thread producerThread = new Thread(new Producer(queue));
        Thread consumerThread = new Thread(new Consumer(queue));
        producerThread.start();
        consumerThread.start();
    }
}

// 生产者类
class Producer implements Runnable {
    private BlockingQueue<Integer> queue;

    public Producer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            for (int i = 1; i <= 6; i++) {
                System.out.println("生产者生产了: " + i);
                queue.put(i);
                Thread.sleep(150); // 模拟生产过程中的延迟
            }
            queue.put(-1); // 使用特殊值表示结束生产
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

// 消费者类
class Consumer implements Runnable {
    private BlockingQueue<Integer> queue;

    public Consumer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                Integer item = queue.take();
                if (item == -1) {
                    break; // 遇到特殊值,退出循环
                }
                System.out.println("消费者消费了: " + item);
                Thread.sleep(100); // 模拟消费过程中的延迟
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
# 执行结果
生产者生产了: 1
消费者消费了: 1
生产者生产了: 2
消费者消费了: 2
生产者生产了: 3
消费者消费了: 3
生产者生产了: 4
消费者消费了: 4
生产者生产了: 5
消费者消费了: 5
生产者生产了: 6
消费者消费了: 6

LinkedBlockingQueue也是阻塞队列的实现之一,不过它和上面的ArrayBlockingQueue区别在于底层数据结构是由双向链表进行实现。

    // LinkedBlockingQueue源码双向链表
    transient Node<E> head;
    private transient Node<E> last;

戳这,《JavaSouth》作为一份涵盖Java程序员所需掌握核心知识、面试重点的《Java学习进阶指南》。

在这里插入图片描述

我是南哥,南就南在Get到你的有趣评论➕点赞➕关注。

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络 数据链路层2

ALOHA:想发就发 CSMA 载波监听多路访问协议 CS&#xff1a;载波监听&#xff0c;在发送数据之前检测总线上是否有其他计算机在发送数据 1-坚持CSMA:主机想发送消息&#xff0c;需要监听信道&#xff1b; 信道空闲则直接传输信息&#xff1b; 信道忙碌则一直监听&#xff0c;直…

半路出家程序员感受:非科班出身如何转行程序员? 答案在这

&#x1f91f; 基于入门网络安全打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 非科班出身是指那些大学专业为非计算机相关专业的人群&#xff0c;多数人对于计算机基础了解比较少&#xff0c;甚至零基础。这部分人群中有相当多一部分处于对于编程…

dinput8.dll错误应该如何修复呢?五种快速修复dinput8.dll错误的问题

dinput8.dll文件是DirectInput库的一部分&#xff0c;主要负责处理游戏控制器的输入&#xff0c;如键盘、鼠标和游戏手柄等。这个文件通常位于Windows系统的System32文件夹中&#xff0c;是许多游戏和应用程序正常运行所必需的组件。它通过提供一个统一的接口来管理不同类型的输…

软媒市场-为企业提供了高效便捷的软文发布渠道和提升品牌曝光度

软媒市场是软文媒体自助发布平台,作为数字营销领域的一股重要力量,正日益受到企业与个人的青睐。这些平台通过整合海量媒体资源,提供从内容创作到多渠道发布的一站式解决方案,极大地提升了品牌曝光度和市场影响力。 一、平台优势 ‌资源丰富‌:软媒市场汇聚了包括门户网站、行业…

打造主播美颜工具:视频美颜SDK与直播美颜API的集成与优化详解

本篇文章&#xff0c;小编将深入讲解视频美颜SDK与直播美颜API的集成与优化策略&#xff0c;帮助开发者构建出色的主播美颜工具。 一、视频美颜SDK与直播美颜API的核心功能 直播美颜API则提供了实时美颜处理的能力&#xff0c;确保美颜效果在直播过程中流畅呈现&#xff0c;不…

【蔡英丽医生】颈动脉斑块:隐形杀手?揭秘症状与治疗新策略!

在繁忙的生活节奏中&#xff0c;你是否曾关注过隐藏在身体深处的健康隐患——颈动脉斑块&#xff1f;这个看似不起眼的“小东西”&#xff0c;实则可能成为引发中风、记忆力衰退等严重疾病的幕后黑手。今天&#xff0c;就让我们一起揭开颈动脉斑块的神秘面纱&#xff0c;了解它…

c++--智能指针(RAII)

智能指针可以帮助我们管理动态空间&#xff0c;即自动释放动态空间。 --------------------------------------------------------------------------------------------------------------------------------- 简单原理 事实上&#xff0c;智能指针的原理就是将指向动态空间…

一目了然的图解一般AI与AI Agent到底区别在哪

全部使用Midjourney绘成&#xff0c;绘制魔法放出自取 魔咒1 Lego shaped Skywalker Luke and Lego shaped Anakin battle --niji 6 --ar 1:1 魔咒2 Lego-style Luke Skywalker and Lego-style Anakin are sitting in a caf talking. --niji 6 --ar 1:1 魔咒3 Anakin in …

18、Gemini-Pentest-v2

难度 中 目标 root权限 一个flag 靶机启动环境为VMware kali 192.168.152.56 靶机 192.168.152.63 信息收集 web测试 访问80端口 上面介绍了一下这个系统是一个内部系统&#xff0c;让员工查看他们的个人资料还可以导出为PDF 页面还有一个链接是UserList可以访问但是页面什…

【自然语言处理】调用NLTK数据失败‘wordnet‘和‘punkt‘不存在[Errno 11004]问题解决

wordnet报错 明明已经按照了nltk包&#xff0c;但使用 WordNet 语料库时依然报错提示数据不存&#xff0c;依据以下代码在python中下载wordnet仍然报错&#xff1a; import nltk nltk.download(wordnet)运行后始终提示&#xff1a; [nltk_data] Error loading wordnet: <…

【算法】PageRank

一、引言 PageRank是由谷歌创始人拉里佩奇和谢尔盖布林在斯坦福大学读研究生时发明的一种算法&#xff0c;用于衡量网页的重要性。它基于一个简单的假设&#xff1a;更重要的网页会有更多的链接指向它。 二、算法原理 PageRank算法的核心思想是&#xff0c;一个网页的重要性可以…

如何找到适合的IT外包服务商

在信息技术迅速发展的今天&#xff0c;IT外包服务已成为企业运营中不可或缺的一部分。选择合适的IT外包服务商对于确保项目成功、提高效率和降低成本至关重要。下面一起探讨评估和选择IT外包服务商的关键因素。 关键因素一&#xff1a;专业资质与认证 选择IT外包服务商时&…

ROS 工具箱系统要求

ROS 工具箱系统要求 要为 ROS 或 ROS 2 生成自定义消息&#xff0c;或从 MATLAB 或 Simulink 软件中部署 ROS 或 ROS 2 节点&#xff0c;您必须构建必要的 ROS 或 ROS 2 软件包。要构建这些软件包&#xff0c;您必须具备 Python 软件、CMake 软件以及适用于您的平台的 C 编译器…

分支和循环以及猜数字游戏的实现

分支和循环以及猜数字游戏的实现目录 随机书生成randsrandtime设置随机数的范围 猜数字游戏的实现 随机书生成 rand C语言中有一个函数叫rand函数&#xff0c;它可以生成随机数&#xff0c;代码格式如下&#xff1a; int rand&#xff08;void&#xff09;rand函数会返回一个…

Unity(2022.3.41LTS) - UI详细介绍- Button(按钮)TMP

目录 零.简介 一、基本功能与重要性 二、属性和设置详解 三、使用方法深入探讨 四、优化和注意事项 零.简介 在 Unity 中&#xff0c;按钮&#xff08;Button&#xff09;是用户界面中非常重要的交互元素之一。以下是对 Unity 中按钮的更详细介绍&#xff1a; 一、基本功…

【docker】docker 是什么

docker 是什么 Docker 本质Docker 的引擎迭代Docker 和虚拟机的区别Docker 为什么比虚拟机资源利用率高&#xff0c;启动快Docker 和 JVM 虚拟化的区别&#xff1f; Docker 本质 Docker 本质其实是 LXC 之类的增强版&#xff0c;它本身不是容器&#xff0c;而是容器的易用工具…

《黑神话:悟空》背后的渲染技术解析

《黑神话&#xff1a;悟空》作为备受瞩目的国产单机游戏&#xff0c;承载了深厚的文化底蕴&#xff0c;其背后的渲染技术无疑是推动其视觉表现达到新高度的关键。这款游戏不仅融合了传统与创新的角色设计&#xff0c;还通过一系列前沿的图形渲染技术&#xff0c;为玩家带来了前…

JVM面试(三)类加载过程

什么是类加载&#xff1f; 前面的文章已经说过&#xff0c;我们手动敲代码&#xff0c;写出来的文件是.java文件。 虚拟机编译之后&#xff0c;可识别的文件是.class文件。 但是在真正运行的时候&#xff0c;在内存中进行各种流转&#xff0c;通过程序来进行执行的时候&#…

【深度解析】GPT-3.5、GPT-4.0、GPT-4o mini的区别,你了解多少?

在人工智能的浪潮中&#xff0c;GPT系列模型如同璀璨的明星&#xff0c;吸引着无数开发者和研究者的目光。随着技术的不断进步&#xff0c;OpenAI推出了多个版本的GPT模型&#xff0c;其中GPT-3.5、GPT-4.0、GPT-4o mini各具特色。今天&#xff0c;我们就来深入探讨它们之间的区…

Odoo:开源免费的OMS订单管理系统

企业全渠道订单管理服务平台 开源智造Odoo免费开源ERP全渠道订单管理应用包含渠道分销订单、零售订单、电商订单、直销订单四部分&#xff0c;主要服务于核心企业的渠道信息化管理&#xff0c;帮助企业从传统分销向移动互联、电商直销或渠道数字化订货转型、新零售转型&#xf…