0

0

什么是Java中的ArrayDeque类_无容量限制的双端队列高效实现

P粉602998670

P粉602998670

发布时间:2026-03-03 12:00:02

|

826人浏览过

|

来源于php中文网

原创

arraydeque 是基于循环数组实现的双端队列,非随机访问、不存 null、内存紧凑;相比 arraylist 不支持 o(1) 索引访问,相比 linkedlist 无节点开销且缓存友好;扩容为 2 倍、容量需为 2 的幂;addfirst 等方法失败抛 illegalstateexception,应优先用 offerfirst;非线程安全,多线程需用 concurrentlinkeddeque 或显式锁。

什么是java中的arraydeque类_无容量限制的双端队列高效实现

ArrayDeque 是什么,和 ArrayList、LinkedList 有什么实际区别

它不是“无容量限制”的动态数组,而是基于循环数组实现的双端队列——扩容时复制整个数组,但平均操作成本低;和 ArrayList 比,它不支持按索引随机访问(get(int) 是 O(n));和 LinkedList 比,它没有节点对象开销,内存更紧凑,且缓存局部性更好。

  • 用作栈(push/pop)或队列(offerFirst/pollLast)时,ArrayDeque 几乎总是比 LinkedList
  • 不要用 ArrayDeque 替代 ArrayList 存数据并频繁调用 get(i)——性能会断崖式下跌
  • 它不允许 null 元素,插入 null 会直接抛 NullPointerException

初始化时指定初始容量到底有没有用

有用,但只在明确知道元素规模时才值得设。默认构造器初始容量是 16,每次扩容为 2 倍,扩容代价是数组拷贝。如果预估要存 1000 个元素,直接 new ArrayDeque(1024) 能避免 4–5 次扩容。

  • 容量必须是 2 的幂次方,传入非 2 幂值(如 100)会被自动向上取整到最近的 2 幂(即 128)
  • 传 0 或负数会触发默认容量(16),不会报错也不会警告
  • 过度预留(比如预设 100 万容量但只存几十个)会浪费堆内存,尤其在大量小实例场景下

为什么用 addFirst 会抛 IllegalStateException

不是因为“满了”,而是因为底层数组已满且无法扩容——这通常只发生在极端内存紧张或人为设置极小初始容量后持续添加时。更常见的是你误用了 addFirst 而非 offerFirst:前者失败直接抛异常,后者返回 false

XiaoHu.AI
XiaoHu.AI

由小互建立的一个AI资讯、教程、课程、工具以及开源项目案例的平台。

下载
  • addFirst / addLast / add 都是继承自 Deque 接口的“强制添加”方法,失败必抛 IllegalStateException
  • 生产代码里优先用 offerFirstofferLast,它们在扩容失败时返回 false,便于你做降级处理
  • JVM 堆足够时几乎不会扩容失败,真遇到这个异常,先查 GC 日志和 -Xmx 设置,而不是怪 ArrayDeque

多线程环境下能不能直接用 ArrayDeque

不能。它没有任何内部同步机制,连基本的 size() 都可能返回错误值——因为 size 是遍历计算的,而遍历时其他线程可能正在增删元素。

立即学习Java免费学习笔记(深入)”;

  • 别试图用 Collections.synchronizedDeque(new ArrayDeque()):它只同步单个方法,复合操作(如“检查是否为空再弹出”)仍会出错
  • 需要线程安全双端队列时,选 ConcurrentLinkedDeque(无锁、弱一致性)或外层加显式锁(如 ReentrantLock 包裹操作块)
  • 如果只是单生产者单消费者,且能控制线程生命周期,用 ArrayDeque + 手动内存屏障(如 volatile 标记位)有时更高效,但极易出错,不推荐新手碰

它快、省、接口干净,但所有优势都建立在“你清楚自己在做什么”这个前提上。一旦混进 null、跨线程、随机访问或容量误判,表现就远不如名字听起来那么可靠。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

251

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

987

2024.03.01

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

910

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

598

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

294

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

210

2025.08.29

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

75

2025.10.23

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1770

2023.10.19

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

0

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4万人学习

C# 教程
C# 教程

共94课时 | 10.5万人学习

Java 教程
Java 教程

共578课时 | 75.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号