LinkedHashMap详解:保持插入顺序的Map实现
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《LinkedHashMap作用解析:保持插入顺序的Map实现》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
LinkedHashMap与HashMap的区别在于前者维护插入顺序,后者不保证顺序。1.LinkedHashMap继承HashMap并用双向链表记录顺序,遍历时按插入顺序访问;2.HashMap查找效率更高但无序;3.当需要顺序或实现LRU缓存时应使用LinkedHashMap;4.LinkedHashMap通过accessOrder参数和removeEldestEntry方法支持LRU策略;5.其迭代性能略低于HashMap但空间开销稍大。

LinkedHashMap在Java中主要作用是提供一个可以记住键值对插入顺序的Map实现。这意味着当你遍历LinkedHashMap时,你会按照元素被添加到Map中的顺序访问它们。这在某些需要维护元素顺序的场景下非常有用。

保持插入顺序的Map实现

LinkedHashMap继承自HashMap,但它通过维护一个双向链表来记录元素的插入顺序。因此,它在HashMap的基础上增加了顺序性。
LinkedHashMap与HashMap的区别是什么?什么时候应该使用LinkedHashMap?
HashMap不保证元素的顺序,而LinkedHashMap保证元素的插入顺序。当你需要按照元素插入的顺序来遍历Map时,应该使用LinkedHashMap。例如,LRU缓存的实现就非常适合使用LinkedHashMap。HashMap查找效率更高(平均情况下),但是不保证顺序。LinkedHashMap在迭代时会有额外的开销,因为它需要维护链表。

具体来说,如果你的应用场景对顺序没有要求,且性能是首要考虑因素,那么HashMap可能是更好的选择。但如果顺序很重要,或者你需要实现一些特殊的缓存策略(如LRU),那么LinkedHashMap就是理想的选择。
LinkedHashMap是如何实现保持插入顺序的?
LinkedHashMap内部维护了一个双向链表,它连接了所有Map中的Entry。每次插入或访问元素时,LinkedHashMap会更新这个链表,以保证链表中元素的顺序与插入顺序一致。
具体来说,LinkedHashMap内部的Entry类除了包含key、value和hash值外,还包含before和after两个指针,分别指向链表中的前一个和后一个Entry。当put一个新的键值对到LinkedHashMap中时,新的Entry会被添加到链表的末尾。当访问一个已存在的键值对时,如果accessOrder设置为true(默认是false,即保持插入顺序),那么这个Entry会被移动到链表的末尾。
如何使用LinkedHashMap实现一个简单的LRU缓存?
LRU (Least Recently Used) 缓存是一种常见的缓存淘汰策略,它会移除最近最少使用的元素。使用LinkedHashMap可以很容易地实现一个LRU缓存。
import java.util.LinkedHashMap; import java.util.Map; public class LRUCacheextends LinkedHashMap { private int capacity; public LRUCache(int capacity) { super(capacity, 0.75f, true); // accessOrder = true this.capacity = capacity; } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > capacity; } public static void main(String[] args) { LRUCache cache = new LRUCache<>(3); cache.put("A", 1); cache.put("B", 2); cache.put("C", 3); System.out.println(cache); // {A=1, B=2, C=3} cache.get("A"); System.out.println(cache); // {B=2, C=3, A=1} cache.put("D", 4); System.out.println(cache); // {C=3, A=1, D=4} B被移除了 } }
这段代码的关键在于LinkedHashMap的构造函数中的accessOrder = true,以及重写removeEldestEntry方法。当accessOrder为true时,每次访问元素都会将其移动到链表末尾。removeEldestEntry方法会在每次put新元素时被调用,如果返回true,则会移除链表头部的元素,也就是最久未使用的元素。
LinkedHashMap的性能如何?与HashMap相比有什么差异?
LinkedHashMap在插入和删除操作上的性能与HashMap相似,都是O(1)(平均情况下)。但是,由于LinkedHashMap需要维护一个双向链表,所以在迭代时会有额外的开销。HashMap的迭代时间复杂度是O(capacity),而LinkedHashMap的迭代时间复杂度是O(size),其中capacity是HashMap的容量,size是Map中元素的数量。因此,当Map中的元素数量远小于容量时,LinkedHashMap的迭代性能可能会更好。
总的来说,如果对顺序有要求,且Map中的元素数量不大,那么LinkedHashMap的性能是可以接受的。但如果对性能要求非常高,且不需要保证顺序,那么HashMap可能更适合。另外,需要注意的是,LinkedHashMap的空间复杂度略高于HashMap,因为它需要额外的空间来存储链表节点。
本篇关于《LinkedHashMap详解:保持插入顺序的Map实现》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!
iPhone安装DeepSeek入门指南
- 上一篇
- iPhone安装DeepSeek入门指南
- 下一篇
- Go语言替换字符串字符技巧
-
- 文章 · java教程 | 2小时前 |
- Java Optional.orElse 和 orElseGet 为什么执行时机不同
- 138浏览 收藏
-
- 文章 · java教程 | 3小时前 |
- Java SequencedCollection 反向遍历怎么避免复制列表
- 431浏览 收藏
-
- 文章 · java教程 | 5小时前 | Java · Switch · pattern matching ·
- Java pattern matching for switch 遇到 null 分支怎么写
- 274浏览 收藏
-
- 文章 · java教程 | 6小时前 | Java · 类型系统 · sealed-interface ·
- Java sealed interface 的 permitted subclasses 怎么影响扩展
- 266浏览 收藏
-
- 文章 · java教程 | 8小时前 | JSON · Java教程 · Jackson · Java record · 数据映射 · jackson Java record JSON 反序列化 额外字段 JsonIgnoreProperties
- Java record 反序列化时如何处理额外 JSON 字段
- 380浏览 收藏
-
- 文章 · java教程 | 9小时前 | Java · 虚拟线程 · 并发任务 · StructuredTaskScope · 结构化并发 ·
- Java 结构化并发预览 API 怎么确保子任务一起结束
- 341浏览 收藏
-
- 文章 · java教程 | 10小时前 | 并发 · Java · 虚拟线程 · synchronized pinning Java virtual thread
- Java virtual thread 使用 synchronized 后为什么仍会阻塞平台线程
- 457浏览 收藏
-
- 文章 · java教程 | 11小时前 | 并发编程 · Java教程 · 性能选型 · java LongAdder AtomicLong 高并发计数
- Java LongAdder 计数高并发时为什么比 AtomicLong 更适合
- 243浏览 收藏
-
- 文章 · java教程 | 12小时前 | Java · 性能 · nio · 文件映射 · java nio FileChannel MappedByteBuffer FileChannel.map
- Java NIO FileChannel 映射文件过大时怎么控制内存占用
- 391浏览 收藏
-
- 文章 · java教程 | 14小时前 | Java · Stream · nio · 文件遍历 · java path Stream Files.walk Files.find
- Java Files.walk 的深度参数为什么不影响当前目录
- 178浏览 收藏
-
- 文章 · java教程 | 15小时前 |
- Java Pattern 匹配 Unicode 字符时怎么选择 UNICODE_CHARACTER_CLASS
- 347浏览 收藏
-
- 文章 · java教程 | 16小时前 | Java教程 · 类型系统 · 编译排错 · sealed interface · java 编译错误 sealed interface permits 密封接口
- Java sealed interface 扩展失败时怎么检查 permits 列表
- 128浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 46次使用
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 198次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 133次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 66次使用
-
- Generrated
- Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
- 47次使用
-
- 矩阵主副对角线快速定位技巧
- 2026-05-31 501浏览
-
- Java多态优化流程代码与行为分发改进
- 2026-05-26 501浏览
-
- JVM 类元数据双亲委派链表深度解析
- 2026-05-21 501浏览
-
- 反射异常处理:InvocationTargetException解析与应用
- 2026-05-16 501浏览
-
- 怎么通过 HTML 的 accesskey 属性为网页中的按钮或链接设置键盘快捷键
- 2026-05-04 501浏览
