ArrayDeque作为双端队列的使用方法

ArrayDeque是Java中高效的双端队列实现,基于数组实现,支持在两端高效添加和移除元素,性能优于LinkedList,适用于和队列场景。它具备均摊O(1)的时间复杂度,内存连续,缓存友好,常用于BFS、LRU缓存、回文检查等场景,但不支持null元素且非线程安全,使用时应优先通过Deque接口声明,必要时选择并发替代方案。

arraydeque作为双端队列的使用方法

ArrayDeque,作为Java集合框架中一个相当实用的双端队列实现,它的核心价值在于提供了一个可以在两端高效地添加和移除元素的动态数组。简单来说,它既能当栈用(后进先出),也能当队列用(先进先出),而且在大多数操作上,它的性能表现都非常出色,通常比LinkedList作为双端队列要快。

解决方案

使用ArrayDeque作为双端队列其实非常直观。你首先需要实例化一个ArrayDeque对象,然后就可以利用它提供的方法在队列的两端进行操作了。

import java.util.ArrayDeque;import java.util.Deque;public class ArrayDequeUsage {    public static void main(String[] args) {        // 声明时通常使用Deque接口,这是一种好的编程习惯        Deque names = new ArrayDeque();        // 在队尾添加元素 (作为队列的入队操作)        names.addLast("Alice"); // 等同于 names.add("Alice"); 或 names.offer("Alice");        names.offer("Bob");        // 在队头添加元素 (作为栈的入栈操作)        names.addFirst("Charlie");        names.push("David"); // push方法是Deque接口特有的,语义上更明确为“入栈”        System.out.println("当前队列内容: " + names); // 输出: [David, Charlie, Alice, Bob]        // 从队头移除元素 (作为队列的出队操作)        String firstElement = names.removeFirst(); // 等同于 names.remove(); 或 names.poll();        System.out.println("移除队头元素: " + firstElement); // David        System.out.println("移除后队列: " + names); // [Charlie, Alice, Bob]        // 从队尾移除元素 (作为栈的出栈操作)        String lastElement = names.removeLast(); // 等同于 names.pop();        System.out.println("移除队尾元素: " + lastElement); // Bob        System.out.println("移除后队列: " + names); // [Charlie, Alice]        // 查看队头元素但不移除        String peekFirst = names.peekFirst(); // 等同于 names.peek();        System.out.println("查看队头元素: " + peekFirst); // Charlie        // 查看队尾元素但不移除        String peekLast = names.peekLast();        System.out.println("查看队尾元素: " + peekLast); // Alice        // 检查队列是否为空        System.out.println("队列是否为空? " + names.isEmpty()); // false        // 获取队列大小        System.out.println("队列大小: " + names.size()); // 2    }}

这段代码展示了ArrayDeque作为双端队列的基本操作。你会发现,它提供了一系列方法,有的名称更偏向队列(如

addLast

/

offer

removeFirst

/

poll

),有的则更偏向栈(如

push

pop

)。这种灵活性正是其魅力所在。

ArrayDeque与LinkedList作为双端队列的性能差异和选择考量

在Java里,除了ArrayDeque,LinkedList也能实现Deque接口,作为双端队列来用。那么,什么时候用哪个呢?坦白说,对于纯粹的双端队列操作,ArrayDeque几乎总是更好的选择

ArrayDeque底层是基于数组实现的,它在内存中是连续存放的。这意味着在访问元素时,CPU缓存的命中率会很高,这对于性能来说是个巨大的优势。它的添加和移除操作(在两端)都是均摊O(1)的时间复杂度。为什么是均摊呢?因为它在内部数组满的时候需要扩容,扩容操作是O(n)的,但这种操作不常发生,所以平均下来还是非常高效的。

而LinkedList呢,它是一个双向链表。每个元素(节点)都包含数据以及指向前一个和后一个节点的引用。虽然在链表的两端添加和移除元素也是O(1),但它的内存是非连续的。这意味着每次访问元素时,都可能需要跳到内存的不同位置,这会降低CPU缓存的效率。此外,每个节点都需要额外的内存来存储前后引用,所以LinkedList的内存开销通常会比ArrayDeque大一些。

所以,我的建议是:

优先选择ArrayDeque:如果你只需要一个高效的双端队列,并且不需要在队列中间频繁插入或删除元素(因为这会让LinkedList的O(1)优势发挥不出来),ArrayDeque是首选。它性能更好,内存效率也更高。考虑LinkedList的情况:只有当你需要处理

null

元素(ArrayDeque不允许)或者确实需要在队列的任意位置进行高效的插入和删除操作时(虽然这已经超出了“双端队列”的范畴,更像是一个通用链表的使用场景),才应该考虑LinkedList。

我个人在实际项目中,只要是用到栈或队列,几乎都是无脑ArrayDeque,因为它在绝大多数场景下都能提供令人满意的性能。

ArrayDeque在实际开发中的应用场景举例

ArrayDeque的用途非常广泛,因为它兼具栈和队列的特性,使得它在处理各种数据结构和算法问题时都游刃有余。

一个非常经典的场景是广度优先搜索 (BFS)。在图或树的遍历中,BFS需要一个队列来存储待访问的节点。每访问一个节点,就将其所有未访问的邻居节点入队。ArrayDeque在这里就完美扮演了队列的角色:

addLast()

用于入队,

removeFirst()

用于出队。

// 伪代码示例:BFS遍历// Deque queue = new ArrayDeque();// queue.addLast(startNode);// while (!queue.isEmpty()) {//     Node current = queue.removeFirst();//     // 处理current节点//     // 将current的未访问邻居节点添加到queue.addLast()// }

另一个非常实用的场景是实现最近最少使用 (LRU) 缓存。LRU缓存的核心思想是:当缓存空间不足时,淘汰掉最近最少使用的那个数据。这通常可以通过结合

HashMap

ArrayDeque

(或者更常见的

LinkedHashMap

,它内部已经实现了类似逻辑)来实现。ArrayDeque可以用来维护一个访问顺序:每当一个元素被访问,就把它移到队列的队尾(表示最近使用过);当需要淘汰时,就从队头移除元素(表示最久未使用)。

// 伪代码示例:LRU缓存的访问顺序维护// Map cacheMap = new HashMap();// Deque accessOrder = new ArrayDeque(); // 队头是LRU,队尾是MRU// void put(Key k, Value v) {//     if (cacheMap.containsKey(k)) {//         accessOrder.remove(k); // 移除旧位置//     } else if (cacheMap.size() >= CAPACITY) {//         Key lruKey = accessOrder.removeFirst(); // 淘汰最旧的//         cacheMap.remove(lruKey);//     }//     cacheMap.put(k, v);//     accessOrder.addLast(k); // 标记为最近使用// }// Value get(Key k) {//     if (cacheMap.containsKey(k)) {//         accessOrder.remove(k); // 移除旧位置//         accessOrder.addLast(k); // 标记为最近使用//         return cacheMap.get(k);//     }//     return null;// }

此外,它还可以用于:

回文检查:将字符串字符依次入队,然后从两端同时取出字符进行比较。滑动窗口最大/最小值问题:维护一个单调队列(通常用ArrayDeque实现),存储窗口内元素的索引,队头始终是当前窗口的最大/最小值。表达式求值:在处理逆波兰表达式或中缀转后缀时,栈是必不可少的,ArrayDeque可以高效地扮演这个角色。

这些场景都体现了ArrayDeque在需要高效地从两端操作数据时的强大能力。

使用ArrayDeque时可能遇到的常见陷阱与最佳实践

尽管ArrayDeque非常强大,但在使用时还是有一些需要注意的地方,避免踩坑。

首先,一个非常重要的点是ArrayDeque不是线程安全的。如果你在多线程环境下使用ArrayDeque,并且有多个线程同时对其进行读写操作,那么就可能会出现数据不一致的问题。在这种情况下,你需要自己进行外部同步(例如使用

Collections.synchronizedDeque()

包装,或者手动加锁),或者考虑使用

java.util.concurrent.ConcurrentLinkedDeque

,它是专门为并发环境设计的双端队列。我个人在写多线程代码时,如果需要并发队列,会直接选择

ConcurrentLinkedDeque

,省去自己同步的麻烦。

其次,ArrayDeque不允许存储

null

元素。如果你尝试

addFirst(null)

addLast(null)

,它会直接抛出

NullPointerException

。这一点与LinkedList不同,LinkedList是允许存储null的。所以在处理可能包含null的数据时,要特别小心,最好在入队前进行null检查。

再者,关于初始容量。ArrayDeque在创建时可以指定一个初始容量。虽然它会自动扩容,但如果你能预估大致的元素数量,提供一个合适的初始容量可以减少扩容的次数,从而在一定程度上提升性能。例如,

new ArrayDeque(100)

。不过,对于大多数应用来说,默认容量(通常是16)也足够了,扩容的开销通常可以忽略不计。过度优化初始容量,反而可能增加代码的复杂性。

最后,一个最佳实践是始终使用

Deque

接口来声明你的ArrayDeque对象,例如

Deque names = new ArrayDeque();

。这是一种面向接口编程的好习惯。它让你的代码更加灵活,如果未来你需要切换到其他Deque实现(比如ConcurrentLinkedDeque),修改起来会更方便,也提高了代码的可读性和可维护性。

总的来说,ArrayDeque是一个非常值得信赖且高效的数据结构。理解它的底层原理和特性,并注意上述的几个点,就能在实际开发中充分发挥它的优势。

以上就是ArrayDeque作为双端队列的使用方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/76704.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月14日 17:09:20
下一篇 2025年11月14日 17:43:58

相关推荐

  • iQOO手机能装币安吗?iQOO怎么安装币安

    iQOO手机可安全安装币安App,需通过官网下载APK、开启未知来源权限并配置三重安全防护。1. 从币安官网或合规链接获取认证APK;2. 进入【设置】→【安全与隐私】→【安装未知应用】启用浏览器权限,并关闭纯净模式;3. 安装后核对开发者信息为“Binance Holdings Limited”,…

    2025年12月8日
    000
  • 2025年最受欢迎的稳定币行情App,一键查看USDT/USDC实时汇率

    在快节奏的数字资产世界中,实时掌握稳定币的汇率至关重要。本文为您精选了2025年最受欢迎的几款稳定币行情app,帮助您轻松、准确地查看usdt、usdc等主流稳定币的实时价格和汇率信息。 稳定币行情App推荐榜单 1. 币安 (Binance)  官网直达: 作为全球交易量最大的加密货币交易所,币安…

    2025年12月8日
    000
  • 2025虚拟币看盘软件排名 目前最稳定最安全的虚拟币看盘软件前十名推荐

    在快速变化的数字资产市场中,选择一款稳定、安全且功能强大的虚拟币看盘软件至关重要。这类工具不仅提供实时的价格行情,还集成了深入的市场分析、图表工具和数据聚合功能,是投资者制定交易策略、把握市场动态不可或缺的助手。本文将为您盘点2025年表现优异的虚拟币看盘软件,帮助您找到最适合自己的选择。 一、选择…

    2025年12月8日
    000
  • 为什么币安账号注册失败?原因与解决方案

    币安账号注册失败主要由地区IP封锁、网络异常、KYC认证失败、账户重复、设备兼容问题及系统维护导致,1使用非受限地区节点并确保网络稳定;2提交清晰完整的证件信息并匹配国籍;3采用未绑定过的邮箱注册;4清理浏览器缓存或更换设备;5避开维护时段并关注官方公告;6注册后立即启用2FA、地址白名单与反钓鱼码…

    2025年12月8日
    000
  • Crypto Raiders (RAIDER币)是什么?RAIDER币主要特点、发展前景及价格预测

    目录 什么是Crypto Raiders (RAIDER)?RAIDER币是什么?Crypto Raiders (RAIDER)的历史RAIDER币的特点Crypto Raiders (RAIDER)如何运作?RAIDER币的发展前景Raider价格预测Raider 2025 年价格预测Raider…

    2025年12月8日
    000
  • MCVT豪掷4.5亿融资Sui,能否复制 “微策略” 神话?

    目录 两大机构联手推动 SUI 微策略:Karatage、Sui 基金会登场总结 ‍7 月 28 日,mill city ventures iii, ltd.(股票代码:mcvt)宣布启动一项高达 4.5 亿美元的私募融资计划,旨在全面实施其 sui 财库战略。此轮融资由对冲基金 karatage …

    2025年12月8日 好文分享
    000
  • 比特币(BTC)储备公司解释:为何要花2美元买1美元的BTC?

    目录 第一部分:股票(ATM)第二部分:债务(杠杆)全栈式加密储备公司的成长路径是什么?山寨币财库储备公司呢?总结‍ 一家比特币财库储备公司的目标是什么?是提高每股比特币的比例,即公司持有的比特币总量与公司完全稀释后的股份数量之间的比率。 微策略(Microstrategy)公司并非试图通过比特币交…

    2025年12月8日 好文分享
    000
  • 币圈主流的玩币软件有哪些

    2025年主流玩币软件的选择需优先考虑安全性、费率、币种覆盖与创新功能,1. 全球综合平台如币安(190亿美元日均量、1600+币种)、欧易(125倍杠杆、Web3集成)、Coinbase(合规标杆、学习赚币)适合多数用户;2. 高潜力特色平台如Gate.io(极速上币、交易即挖旷3.0)、库币(G…

    2025年12月8日
    000
  • 炒币跟炒股有什么区别?哪个风险大?更赚钱

    加密货币与股票的差异在于资产本质、市场机制和风险收益特征,1. 股票代表企业所有权,价值基于盈利与分红,受监管且交易时间有限,年化回报约10%,适合中长期投资者;2. 加密货币依赖市场共识与技术应用,24小时交易、无涨跌幅限制,波动剧烈,比特币历史年均回报达46.6%但回撤常超80%,风险更高;3.…

    2025年12月8日
    000
  • 什么是Axelar Network(AXL币)?一文介绍

    目录 什么是Axelar,为何它如此重要?Axelar 的关键特征谁创建了Axelar?Axelar在2025年的重要发展Axelar如何运作?验证者与安全性中继服务与油费接收者开发者工具:CLI、SDK和API什么是AXL,Axelar 网路的原生代币?结论  如果区块链无法相互沟通,它们如何才能…

    2025年12月8日 好文分享
    000
  • 8月加密交易员不可错过的5大经济事件:你的 BTC 与 ETH 投资攻略

    目录 关键要点8月宏观与政策一览8月必看重大事件8月每周经济日历拆解第1周:8月1日–7日第2周:8月8日–14日第3周:8月15日–21日第4周:8月22日–28日第5周:8月29日–31日风险管理与注意事项关于8月经济日历的常见问题 关键要点 – 影响比特币和以太坊波动最大的日期有:8月1日(美…

    2025年12月8日 好文分享
    000
  • 哪些社区活动发放 USDC 奖励?值得关注的平台与方式

    在当前稳定币生态中,usdc作为合规透明的代表,越来越多社区选择以 usdc 作为任务激励、参与奖品或内容创作奖励。本文将介绍值得关注的几个社区活动平台及其发放 usdc 奖励的方式,帮助用户把握获取机会。 Binance币安 官网直达: 安卓安装包下载: 欧易OKX ️ 官网直达: 安卓安装包下载…

    2025年12月8日
    000
  • 使用 USDC 参与 DeFi 锁仓可获空投奖励?最新项目整理

    2025年加密生态进入精细化运营阶段,许多 defi 协议开始以锁仓usdc的方式奖励早期参与者。相比一般交互任务,这类锁仓型空投更侧重用户的资产沉淀意愿,具备更高的空投回报潜力。本文将整理近期可通过 usdc 锁仓获得代币或稳定币空投的主要项目,便于用户评估参与方式与风险门槛。 Binance币安…

    2025年12月8日
    000
  • Fartcoin(FARTCOIN币)价格预测2025-2030年:未来价格能到多少?

    目录 什么是fartcoin(fartcoin)? 市场表现:过山车般的价格旅程 价格波动的核心驱动因素 今天、明天和未来 30 天的价格预测 Fartcoin(FARTCOIN)2025-2030年价格预测 Fartcoin(FARTCOIN)2025年每月价格预测 2026年Fartcoin(F…

    2025年12月8日
    000
  • 以太坊是什么币?以太坊ETH获得的方式有哪些?

    以太坊是一个基于智能合约的去中心化应用平台,其原生代币ETH可通过多种方式获取。1、通过Binance必安、欧意ok等中心化平台注册账户、完成KYC认证并用稳定币购买ETH;2、通过去中心化平台连接数字储存,使用稳定币或其他代币直接兑换ETH;3、参与网络质押,可选择独立质押(需32个ETH)、流动…

    2025年12月8日
    000
  • 稳定币完全手册:6种主流稳定币类型最新介绍

    稳定币作为数字资产领域的重要组成部分,为市场带来了前所未有的流动性和交易便捷性。它们的设计初衷是为了规避加密货币市场剧烈波动的风险,通过锚定法币或其他资产,试图提供一种相对稳定的价值储存和交换媒介。然而,并非所有稳定币都以相同的方式实现其稳定性,市场上的稳定币种类繁多,各具特色,理解它们的工作原理、…

    2025年12月8日
    000
  • 虚拟币链上交易多久可以到账 不同网络虚拟币转账确认时间说明

    许多新手用户在进行虚拟币转账时,常常会产生疑问:“链上交易为什么还没到账?”其实,加密货币转账是否到账,取决于所在网络的确认机制和网络拥堵情况。不同公链对交易确认的速度存在显著差异,理解这些规则有助于更有效地掌控资产流转过程。本文将结合常见网络的确认时间进行说明。 如果你经常使用链上转账,推荐注册币…

    2025年12月8日
    000
  • 一文全方位了解GENIUS 稳定币法案解析

    2025年7月18日,美国总统签署了《指导与建立美国稳定币国家创新法案》(简称“GENIUS 法案”),标志着美国在数字资产监管领域迈出了历史性的一步。作为美国首部联邦层面的稳定币专项立法,该法案旨在为“支付型稳定币”建立一套全面、清晰的法律和监管框架。 GENIUS 法案的出台,不仅回应了过去稳定…

    2025年12月8日
    000
  • 以太坊价格走势暗示市场动能转移:比特币沉睡,以太坊活跃

    近期,加密货币市场仿佛进入了一个全新的篇章。曾经的“数字黄金”比特币,似乎正在经历一场深沉的休憩,其价格波动幅度显著收窄,市场关注度也略显平淡。与之形成鲜明对比的是,以太坊(ethereum)正以惊人的活力成为市场的焦点。从技术图表到链上数据,再到围绕以太坊生态的创新活动,无不透露出市场动能正在悄然…

    2025年12月8日
    000
  • 以太坊闪耀:美国银行开启数字资产追踪,ETH 再成焦点

    美国银行开启数字资产追踪标志着以太坊在主流金融的认可度提升,1. 合法性认可度提升;2. 可能吸引机构配置数字资产;3. 推动合规化进程;4. 确认ETH作为“数字石油”的应用前景和潜在价值;以太坊成为焦点因其拥有庞大的DApp生态系统,1. 技术升级至PoS提升可扩展性、安全性和可持续性;2. 作…

    2025年12月8日 好文分享
    000

发表回复

登录后才能评论
关注微信