集合源码解析: Stack and Queue精讲 初中级人员

Rocky Linux 8 上源码编译部署 Suricata 7.0.7 完整指南 网络入侵检测系统(IDS)是现代安全基础设施的核心组件,其原理基于深度包检测(DPI)、协议解析与规则匹配,通过实时流量分析识别SQL注入、恶意C2通信等威胁。Suricata 作为高性能开源IDS/IPS引擎,依托Rust重写检测核心、Hyperscan加速正则、AF_PACKET v3零拷贝抓包等关键技术,显著提升检测精度与吞吐能力。在企业级场景中,操作系统底座的稳定性、SELinux兼容性及长期安全支持至关重要——Rocky Linux 8继承RHEL 8内核与模块化架构,成为金融、政务等高合规要求环 阅读详情

前言

集合的重要程度很高 如果不能全面了解 就没法完全发挥它的作用 打好地基才能走得远

Stack & Queue概述

Java里有一个叫做Stack的类,却没有叫做Queue的类(它是个接口名字)。当需要使用栈时,Java已不推荐使用Stack,而是推荐使用更高效的ArrayDeque;既然Queue只是一个接口,当需要使用队列时也就首选ArrayDeque了(次选是LinkedList)。

Queue

Queue接口继承自Collection接口,除了最基本的Collection的方法之外,它还支持额外的*insertion*, *extraction*和*inspection*操作。这里有两组格式,共6个方法,一组是抛出异常的实现;另外一组是返回值的实现(没有则返回null)。

Throws exceptionReturns special value
Insertadd(e)offer(e)
Removeremove()poll()
Examineelement()peek()

Deque

Deque是"double ended queue", 表示双向的队列,英文读作"deck". Deque 继承自 Queue接口,除了支持Queue的方法之外,还支持insert, remove和examine操作,由于Deque是双向的,所以可以对队列的头和尾都进行操作,它同时也支持两组格式,一组是抛出异常的实现;另外一组是返回值的实现(没有则返回null)。共12个方法如下:

First Element - HeadLast Element - Tail
Throws exceptionSpecial valueThrows exceptionSpecial value
InsertaddFirst(e)offerFirst(e)addLast(e)offerLast(e)
RemoveremoveFirst()pollFirst()removeLast()pollLast()
ExaminegetFirst()peekFirst()getLast()peekLast()

当把Deque当做FIFO的queue来使用时,元素是从deque的尾部添加,从头部进行删除的; 所以deque的部分方法是和queue是等同的。具体如下:

Queue MethodEquivalent Deque Method
add(e)addLast(e)
offer(e)offerLast(e)
remove()removeFirst()
poll()pollFirst()
element()getFirst()
peek()peekFirst()

Deque的含义是“double ended queue”,即双端队列,它既可以当作栈使用,也可以当作队列使用。下表列出了Deque与Queue相对应的接口:

Queue MethodEquivalent Deque Method说明
add(e)addLast(e)向队尾插入元素,失败则抛出异常
offer(e)offerLast(e)向队尾插入元素,失败则返回false
remove()removeFirst()获取并删除队首元素,失败则抛出异常
poll()pollFirst()获取并删除队首元素,失败则返回null
element()getFirst()获取但不删除队首元素,失败则抛出异常
peek()peekFirst()获取但不删除队首元素,失败则返回null

下表列出了Deque与Stack对应的接口:

Stack MethodEquivalent Deque Method说明
push(e)addFirst(e)向栈顶插入元素,失败则抛出异常
无offerFirst(e)向栈顶插入元素,失败则返回false
pop()removeFirst()获取并删除栈顶元素,失败则抛出异常
无pollFirst()获取并删除栈顶元素,失败则返回null
peek()getFirst()获取但不删除栈顶元素,失败则抛出异常
无peekFirst()获取但不删除栈顶元素,失败则返回null

上面两个表共定义了Deque的12个接口。添加,删除,取值都有两套接口,它们功能相同,区别是对失败情况的处理不同。一套接口遇到失败就会抛出异常,另一套遇到失败会返回特殊值(false或null) 。除非某种实现对容量有限制,大多数情况下,添加操作是不会失败的。虽然Deque的接口有12个之多,但无非就是对容器的两端进行操作,或添加,或删除,或查看**。明白了这一点讲解起来就会非常简单。

ArrayDeque和LinkedList是Deque的两个通用实现,由于官方更推荐使用AarryDeque用作栈和队列,这个文章主要整理ArrayDeque**的具体实现。

从名字可以看出ArrayDeque底层通过数组实现,为了满足可以同时在数组两端插入或删除元素的需求,该数组还必须是循环的,即循环数组(circular array) ,也就是说数组的任何一点都可能被看作起点或者终点。ArrayDeque是非线程安全的(not thread-safe),当多个线程同时使用的时候,需要程序员手动同步;另外,该容器不允许放入null元素。

上图中我们看到,head指向首端第一个有效元素,tail指向尾端第一个可以插入元素的空位。因为是循环数组,所以head不一定总等于0,tail也不一定总是比head大。

方法剖析

addFirst()

addFirst(E e)的作用是在Deque的首端插入元素,也就是在head的前面插入元素,在空间足够且下标没有越界的情况下,只需要将elements[--head] = e即可。

实际需要考虑: 1.空间是否够用,以及2.下标是否越界的问题。上图中,如果head为0之后接着调用addFirst(),虽然空余空间还够用,但head为-1,下标越界了。下列代码很好的解决了这两个问题。

//addFirst(E e)
public void addFirst(E e) {
    if (e == null)//不允许放入null
        throw new NullPointerException();
    elements[head = (head - 1) & (elements.length - 1)] = e;//2.下标是否越界
    if (head == tail)//1.空间是否够用
        doubleCapacity();//扩容
}

上述代码我们看到,空间问题是在插入之后解决的,因为tail总是指向下一个可插入的空位,也就意味着elements数组至少有一个空位,所以插入元素的时候不用考虑空间问题。

下标越界的处理解决起来非常简单,head = (head - 1) & (elements.length - 1)就可以了,这段代码相当于取余,同时解决了head为负值的情况。因为elements.length必需是2的指数倍,elements - 1就是二进制低位全1,跟head - 1相与之后就起到了取模的作用,如果head - 1为负数(其实只可能是-1),则相当于对其取相对于elements.length的补码。

下面再说说扩容函数doubleCapacity(),其逻辑是申请一个更大的数组(原数组的两倍),然后将原数组复制过去。过程如下图所示:

图中我们看到,复制分两次进行,第一次复制head右边的元素,第二次复制head左边的元素。

//doubleCapacity()
private void doubleCapacity() {
    assert head == tail;
    int p = head;
    int n = elements.length;
    int r = n - p; // head右边元素的个数
    int newCapacity = n << 1;//原空间的2倍
    if (newCapacity < 0)
        throw new IllegalStateException("Sorry, deque too big");
    Object[] a = new Object[newCapacity];
    System.arraycopy(elements, p, a, 0, r);//复制右半部分,对应上图中绿色部分
    System.arraycopy(elements, 0, a, r, p);//复制左半部分,对应上图中灰色部分
    elements = (E[])a;
    head = 0;
    tail = n;
}

addLast()

addLast(E e)的作用是在Deque的尾端插入元素,也就是在tail的位置插入元素,由于tail总是指向下一个可以插入的空位,因此只需要elements[tail] = e;即可。插入完成后再检查空间,如果空间已经用光,则调用doubleCapacity()进行扩容。

public void addLast(E e) {
    if (e == null)//不允许放入null
        throw new NullPointerException();
    elements[tail] = e;//赋值
    if ( (tail = (tail + 1) & (elements.length - 1)) == head)//下标越界处理
        doubleCapacity();//扩容
}

下标越界处理方式addFirt()中已经讲过,不再赘述。

pollFirst()

pollFirst()的作用是删除并返回Deque首端元素,也即是head位置处的元素。如果容器不空,只需要直接返回elements[head]即可,当然还需要处理下标的问题。由于ArrayDeque中不允许放入null,当elements[head] == null时,意味着容器为空。

public E pollFirst() {
    E result = elements[head];
    if (result == null)//null值意味着deque为空
        return null;
    elements[h] = null;//let GC work
    head = (head + 1) & (elements.length - 1);//下标越界处理
    return result;
}

pollLast()

pollLast()的作用是删除并返回Deque尾端元素,也即是tail位置前面的那个元素。

public E pollLast() {
    int t = (tail - 1) & (elements.length - 1);//tail的上一个位置是最后一个元素
    E result = elements[t];
    if (result == null)//null值意味着deque为空
        return null;
    elements[t] = null;//let GC work
    tail = t;
    return result;
}

peekFirst()

peekFirst()的作用是返回但不删除Deque首端元素,也即是head位置处的元素,直接返回elements[head]即可。

public E peekFirst() {
    return elements[head]; // elements[head] is null if deque empty
}

peekLast()

peekLast()的作用是返回但不删除Deque尾端元素,也即是tail位置前面的那个元素。

public E peekLast() {
    return elements[(tail - 1) & (elements.length - 1)];
}
从工具使用者到开发者:网络安全渗透测试工具开发与漏洞挖掘核心技术解析 在网络安全领域,渗透测试是评估系统防御有效性的关键手段。其核心原理在于模拟攻击者行为,通过主动探测和分析来发现潜在的安全弱点。随着网络环境日益复杂,通用自动化扫描工具在应对定制化业务逻辑和新型防御机制时往往力不从心,这凸显了掌握定制化工具开发技术的工程价值。从概念上讲,工具开发不仅提升了测试的针对性和效率,更是实现深度漏洞挖掘的基础。具体到技术实现,现代渗透测试工具通常采用分层架构,涵盖数据采集、核心引擎、插件扩展和交互报告等模块。在漏洞挖掘方面,模糊测试(Fuzzing)作为自动化挖掘的利器,通过覆盖率引 阅读详情

相关推荐

飞书多Agent系统实战:用OpenClaw构建可养、可溯、可进化的AI员工

多Agent系统是企业级AI落地的核心范式,其本质是将复杂业务协作解耦为多个职责明确、契约清晰的智能体。基于行为自主性、状态可追溯与责任可归因三大原则,现代Agent需支持跨角色通信、上下文感知路由与本地化状态持久化。OpenClaw作为面向飞书生态的轻量级Agent运行时,依托Node.js高并发能力与Unix Socket内网通信,实现低延迟、高可靠、数据不出域的私有化部署。它不仅提供标准化技能开发接口和YAML契约配置,更通过多维表格驱动反馈闭环、在线模型训练与规则热加载,支撑AI员工从‘能用’走向‘

diaohong5075的博客 527

Collection - Stack & Queue 源码解析

JDK版本 JDK 1.8.0_110 参考 Stack & Queue概述 Java里有一个叫做Stack的类,却没有叫做Queue的类(它是个接口名字)。当需要使用栈时,Java已不推荐使用Stack,而是推荐使用更高效的ArrayDeque;既然Queue只是一个接口,当需要使用队列时也就首选ArrayDeque了(次选是LinkedList)。 Queue Queue接口继承自Collection接口,除了最基本的Collection的方法之外,它还支持额外的insertion,

。 20万+

技术博客人格化:从.NET开发者视角重构内容生产逻辑

技术博客的本质不是知识搬运,而是构建可信赖的技术对话场域。理解‘人格化技术传播’需先厘清其底层原理:它将抽象API、语法特性与真实开发者的认知路径、调试行为、决策压力深度耦合;其技术价值在于弥合官方文档与工程实践之间的鸿沟,显著提升经验留存率与问题解决效率;典型应用场景包括技术选型决策、性能优化归因、调试异常诊断等高痛点多发领域;而‘老赵点滴’的实践表明,真正有效的技术内容必须锚定在开发者的人格轨迹(如调试截图、版本踩坑、环境元信息)与工程上下文(如Kubernetes资源限制、Azure DevOps流水

as2886089的博客 469

数据结构——单调栈详解

单调栈定义: 从栈底元素到栈顶元素呈单调递增或单调递减,栈内序列满足单调性的栈。 一般用于求解,元素的左边或者右边第一个大于或者小于元素的值。 这里通过一道单调栈的例题进行举例分析。 力扣真题 https://leetcode-cn.com/problems/largest-rectangle-in-histogram/description/ 穷举 其实可以想到的思路是穷举: 以2作为高,计算最大面积; 以1作为高,计算最大面积; 以5作为高,计算最大面积; 以6作为高,计.

mk33092250的博客 1110

微服务架构平台(MSAP)实战:从设计到落地的全链路指南

微服务架构通过将单体应用拆分为独立部署、松耦合的服务,提升了系统的可扩展性与开发敏捷性。其核心原理在于服务自治与分布式通信,这带来了服务发现、配置管理、链路追踪等一系列技术挑战。为应对这些挑战,现代应用架构实践(MSAP)应运而生,它整合了容器化、服务网格和GitOps等云原生技术,旨在构建覆盖应用全生命周期的统一平台。MSAP的核心技术价值在于通过标准化与自动化,显著提升微服务环境的可观测性、部署效率与运维稳定性。典型的应用场景包括企业级微服务治理、持续交付流水线构建以及复杂分布式系统的监控排障。本文以*

Ferrerooo 成长 404

C# C++ 笔记

变量自定义赋值​# 变量取值用$()​​​​​​clean:多个程序员分发同一程序时,由于不能直接在一个程序上进行功能的开发,所以就有了功能分支的概念。二维数组可以理解为是存储指针的一维数组,里面的每一个指针都指向一个一维数组的首地址存储多个一维数组的数据结构。array 是一个二维数组,它有3行和4列,总共可以存储12个整数。

AVICCI的博客 2203

[LeetCode]-栈

LeetCode,栈和队列以及优先队列相关题目

Pacifica_的博客 674

字节AI Agent面试题大全及参考答案(下)

Skill 是大模型 Agent 领域对能力单元的抽象,中文常译作技能,本质是把一类可被 Agent 调用的能力做标准化封装,包含工具调用、业务流程、提示词模板、子 Agent、查询逻辑等,不局限于单纯函数调用。面试加分点,不要把 Skill 等同于普通 function call 函数,要区分 Function、Skill、MCP 三者的边界,讲清楚 Skill 不止是单个函数,可以是复杂业务流程,同时说明 MCP 协议定位是通信协议,不是能力本身。Skill 核心原理,将离散能力封装成具备元信息的独立单

大模型大数据攻城狮的专栏 476

Deque 的pollFirst,pollLast,offerLast

接口中的两个方法,用于从双端队列(Deque)中检索和删除元素。这两者的主要区别在于它们对队列的操作方向。一般来说,如果你只关心是否成功将元素添加到末尾,并且希望避免异常,可以使用。: 从双端队列的尾部(末尾)检索并删除元素。: 从双端队列的头部(开头)检索并删除元素。都用于将元素添加到数据结构的末尾。在Java中的现代编码中,推荐使用。类,并且不关心异常,那么。

呆咖啡的博客 2549

别再只盯着CXL协议了,聊聊CXL.mem里那个能动态调优内存性能的‘QoS遥测’到底怎么用

本文深入解析CXL.mem协议中的QoS遥测功能,探讨如何通过DevLoad指标动态调优内存性能。文章详细介绍了QoS遥测的核心机制、多QoS类别设备的实战配置,以及AI训练、金融交易和视频处理场景中的优化案例,帮助数据中心实现高效内存资源管理。

weixin_33725722的博客 437

关于deque的offerLast和polllast方法和stack的区别

一个小细节:在Java 代码中,stack 并未用 push() 和 pop() ,而用的是 offerLast() 和 pollLast() 。 这是因为 Deque 提供的 push() 和 pop() 是 “头插头取”,这与 ans.add(new ArrayList(stack)); 所需的顺序刚好相反,所以才改用了 “尾插尾取”。(其实我认为既然要 “尾插尾取”,还不如直接使用 List 呢) ...

Charles的博客 2104

coze+飞书多维表格,批量分析小红书笔记,关键还能获取图片(附保姆级教程)

通过coze工作流,一键同步小红书账号和笔记链接到飞书多维表格,效率飞升~

qq_24403067的博客 4176

java 集合相关 The Collections Framework

这里选择的是JDK 1.6版本的源码,为的是暂时不去纠结一些JAVA的新特性,将关注点放在集合本身。一 . 整体了解   有时需要对一组对象进行各种操作。针对不同的应用场景,需要选择合适的数据结构(比如数组,链表,树),以及一些数据内容本身的特性 (比如 可重复,不可重复),因为很多内容是重复的,所以官方提供了这个集合框架 以下是官方给出的说明The Collections Framework 集...

boombaozi的博客 235

在Ubuntu系统中安装和使用wxPython进行Python图形用户界面(GUI)开发

在本文中,我将向您展示如何在Ubuntu系统上安装和使用wxPython,并提供一些示例代码来帮助您开始使用这个强大的工具。在MyFrame的构造函数中,我们创建了一个wx.Panel和一个按钮,并将按钮的点击事件绑定到一个自定义的方法on_button_click上。最后,我们创建了一个wx.App的实例,创建了一个MyFrame对象并显示它,最后通过调用app.MainLoop()启动应用程序的主事件循环。这只是一个简单的示例,但它演示了如何使用wxPython创建一个基本的GUI应用程序。

qq_37934722的博客 1040

滤波算法实现大全——基于匀速直线运动模型的kalman滤波算法

滤波算法实现大全——基于匀速直线运动模型的kalman滤波算法

jane0819的博客 524

集合(二)

备注:若有不正之处,请多谅解并欢迎批评指正。转载请标明链接:https://www.cnblogs.com/pmbb/p/11427724.html 集合(二)对集合(一)做一些简单的补充和复习 集合的作用 在编程中,需要管理很多对象集.比如某班全部同学,某个公司所有人员资料等. 要管理这些资料,java必须提供某种数据结构支持. 由于时间,空间,安全的考虑,有各种不同的实现...

Warhol1221的博客 297

YOLO26改进105:全网首发--使用BiFPN改进特征金字塔网络

YOLOv6 v3.0在目标检测领域实现重大突破,通过改进网络架构和训练方案显著提升性能。该版本在COCO数据集上展现出优越表现:YOLOv6-N达到37.5% AP/1187 FPS,YOLOv6-S实现45.0% AP/484 FPS,均超越同类检测器。大模型YOLOv6-M/L分别达到50.0%/52.8% AP,L6版本更创下实时检测新纪录。关键技术包括RepVGGBlock、BiFusion等新型模块,通过多分支融合和高效重参数化设计提升性能。研究团队已验证各改进模块有效性,代码已开源。

AIcurator的博客 95

源码阅读(1):Java中主要的List结构——概述

典型的数据结构中,对于“表”结构的定义是:在一维空间下元素按照某种逻辑结构进行线性连接排列的数据结构(一对一)。java中集合定义中所包括的链表(ArrayList)、链表(LinkedList)、各种队列(Queue/Deque)、栈(Stack)等都满足这样的定义。本文及后续的几篇文章中将介绍Java集合结构中关于List接口、Queue接口、Set接口下的重要实现类。

JAVA入门中 7339

小论文/大论文必备 | YOLO多模态目标检测、绘制曲线对比图 | 引入多种绘制曲线对比图,包括mAP0.5,mAP0.5:0.95,Loss损失变化的曲线对比

本文通过可视化方法分析YOLO多模态模型的训练过程,对比不同实验的检测精度和损失函数变化。主要内容包括:1)绘制mAP@0.5和mAP@0.5:0.95曲线评估检测精度;2)分析边界框回归损失(box_loss)、分类损失(cls_loss)和分布式损失(dfl_loss)的收敛趋势;3)提供完整的Python代码实现,支持多实验对比,可生成高清曲线图。该方法能直观展示模型训练效果,便于优化策略评估和参数调优。

Ai缝合怪、助力小伙伴高效发论文 262

北斗导航 | 卫星信号捕获跟踪原理解析

卫星信号的捕获与跟踪是导航接收机的"眼睛",其性能直接决定定位精度、动态适应性和抗干扰能力。随着北斗三号全球组网完成,新一代接收机正朝着。两大核心阶段,二者共同构成定位的基础。调制,频谱主瓣宽度达4.092MHz,较传统BPSK调制抗干扰能力提升3dB[38]。的目标持续演进,在自动驾驶、精密农业等领域展现出巨大应用潜力。二维空间中搜索峰值相关能量[4]。卫星导航接收机对信号的处理可分为。北斗三号B1C/B2a信号采用。北斗三号新增的B1C信号采用。

尘世冰封的专栏 783

java list大小限制_Java中主要的List结构——概述

0. 概述典型的数据结构中,对于“表”结构的定义是:在一维空间下元素按照某种逻辑结构进行线性连接排列的数据结构(一对一)。java中集合定义中所包括的数组表(ArrayList)、链表(LinkedList)、各种队列(Queue/Deque)、栈(Stack)等都满足这样的定义。本文及后续的几篇文章中将介绍Java集合结构中关于List接口、Queue接口、Set接口下的重要实现类。注意,关于j...

weixin_30755903的博客 3350

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

每周小记——JVM

本文剖析JVM核心机制:详述内存模型(堆、方法区、栈)及垃圾回收算法(标记-清除/复制/压缩)、分代策略与GC类型(Minor/Major/FullGC);解析类加载机制(双亲委派模型、加载/链接/初始化过程及三类加载器差异);阐述执行引擎(JIT编译、热点探测、逃逸分析);对比现代收集器(G1/ZGC/Shenandoah)及CMS优劣;探讨性能调优关键(吞吐量与延迟平衡、内存分配策略)。为Java性能优化提供理论支撑。

weixin_57655687的博客 1583

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

CPU 缓存 | 原理、映射、一致性

……

u013669912的博客 414

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

147.【2024Java八股-全网最全-10w字】

eg: 学校、院校、经验、年龄、跳槽频率…基本包括16种常见使用场景: 、数据共享分布式、、全局 ID、计数器、限流、位统计、购物车、用户消息时间线 timeline、、抽奖、点赞、签到、打卡、商品标签、商品筛选、用户关注、推荐模型、排行榜.详细讲解16种使用场景: https://blog.youkuaiyun.com/zxl646801924/article/details/123202381用户使用id进行查询文章的时候,首先会查询redis数据库,如果在redis中命中数据,那么redis就向用户返回查询的结果

qq_69683957的博客 1736

练功秘籍---A

常用整理

CarryBest的博客 1655
上一篇: 集合源码解析:ArrayList 精讲 初中级人员
下一篇: 手把手教你如何通过Java给图片添加文字和图片水印
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值