LinkedHashMap维护插入(或访问)顺序,HashMap不保证顺序;前者遍历按插入序,后者顺序不确定;LinkedHashMap内存略高但序列化后顺序仍保留,Java 21 SequencedMap接口进一步明确顺序契约。

LinkedHashMap 会维护插入顺序,HashMap 不保证任何顺序
这是最核心的区别。当你遍历 LinkedHashMap 的 keySet()、values() 或 entrySet() 时,元素顺序严格按插入顺序返回;而 HashMap 的遍历顺序是不确定的,取决于哈希值、容量和扩容过程,甚至同一次 JVM 运行中多次遍历都可能不同。
常见错误现象:用 HashMap 存配置项或操作日志后想“按添加顺序打印”,结果顺序错乱,误以为数据损坏。
- 如果需要访问顺序(比如 LRU 缓存),
LinkedHashMap可通过构造函数传入true启用:new LinkedHashMap
(16, 0.75f, true) -
HashMap在 Java 8+ 中对链表长度 ≥ 8 且桶数组长度 ≥ 64 时会转为红黑树,但该优化不影响顺序语义——它依然不维护顺序 - 两者都允许
null键和null值(LinkedHashMap继承自HashMap,行为一致)
LinkedHashMap 内存开销略大,因为额外维护双向链表节点
LinkedHashMap 每个 Node 实际是 Entry 子类,比 HashMap 的 Node 多两个引用字段:before 和 after。这意味着每个键值对多占用 16 字节(64 位 JVM,对象头 + 引用字段对齐后)。
影响场景:高频创建小集合(如单次请求中新建几十个 LinkedHashMap),内存压力明显高于 HashMap;但对大多数业务场景(几百到几千元素),这点差异可忽略。
立即学习“Java免费学习笔记(深入)”;
- 不要为“看起来更规范”而默认用
LinkedHashMap,没顺序需求就用HashMap - 若只读遍历频繁且需顺序,
LinkedHashMap的迭代性能反而更稳定——HashMap迭代需跳过空桶,实际走的是散列分布路径
序列化行为一致,但反序列化后 LinkedHashMap 仍保持顺序
两者都实现了 Serializable,序列化格式兼容。关键点在于:LinkedHashMap 在反序列化时会重建内部链表,所以顺序信息被完整保留;而 HashMap 反序列化后仍是无序结构。
容易踩的坑:把 HashMap 存进 Redis 或写入 JSON 再读回,误以为“顺序能回来”。实际上 JSON 对象属性顺序在规范中不保证,Jackson 默认也不保留 HashMap 插入顺序(除非显式配 SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS 或换用 LinkedHashMap)。
- 跨进程/网络传输时,若依赖顺序,必须在接收端也用
LinkedHashMap构造(例如 Jackson 反序列化指定类型:mapper.readValue(json, new TypeReference
>() {}) - Spring Boot 配置绑定(
@ConfigurationProperties)默认使用LinkedHashMap解析 YAML/Properties 中的 map,所以配置项顺序通常可保持
替代方案:Java 21+ 的 SequencedMap 接口让顺序语义更明确
Java 21 引入了 SequencedMap,LinkedHashMap 实现了它,而 HashMap 没有。这意味着你可以用接口编程强调顺序契约:
SequencedMapmap = new LinkedHashMap<>(); map.put("a", 1); map.put("b", 2); // 现在可以安全调用: map.reversed(); // 返回逆序视图 map.getFirst(); // O(1) 获取首元素
但注意:SequencedMap 是接口,不是新实现;现有代码无需改,但新 API 设计时值得考虑——它把“顺序”从具体实现(LinkedHashMap)提升为契约,未来其他有序 Map 实现也能自然融入。
别指望 HashMap 某天突然支持顺序:它的设计目标就是高性能哈希查找,顺序是权衡掉的特性。真要顺序,就得接受链表维护成本,或者换用 TreeMap(按 key 排序,非插入序)。










