文章目录
- 怎么选
- [1. `HashMap`](#1.
HashMap) - [2. `LinkedHashMap`](#2.
LinkedHashMap) - [3. `Hashtable`](#3.
Hashtable) - [4. `ConcurrentHashMap`](#4.
ConcurrentHashMap) - [5. `WeakHashMap`](#5.
WeakHashMap) - [6. `IdentityHashMap`](#6.
IdentityHashMap) - [7. `EnumMap`](#7.
EnumMap) - [8. `TreeMap`](#8.
TreeMap) -
- LinkedHashMap
-
-
- [三、LinkedHashMap 的"顺序"是什么?](#三、LinkedHashMap 的“顺序”是什么?)
- 四、为什么它能保持顺序?
- 九、回到你的代码为什么用它
-
常见的 "HashMap" 一般可以分成两层来理解:
一层是 Java 里常见的 Map 实现类 ,另一层是 广义上基于哈希思想的 Map/Set 容器。
| 类 | 是否有序 | 线程安全 | 是否允许 null | 说明 |
|---|---|---|---|---|
HashMap |
否 | 否 | 允许 | 最常用 |
LinkedHashMap |
是 | 否 | 允许 | 保持顺序 |
Hashtable |
否 | 是 | 不允许 | 老方案 |
ConcurrentHashMap |
否 | 是 | 不允许 | 并发首选 |
WeakHashMap |
否 | 否 | 允许 | 弱引用 key |
IdentityHashMap |
否 | 否 | 允许 | 用 == 比较 key |
EnumMap |
枚举顺序 | 否 | key 不可为 null | 枚举专用 |
TreeMap |
排序 | 否 | key 通常不可为 null | 红黑树 |
怎么选
可以直接这样记:
- 只要快,不关心顺序 →
HashMap - 要保持插入顺序 →
LinkedHashMap - 多线程并发 →
ConcurrentHashMap - 要按 key 排序 →
TreeMap
1. HashMap
最常用。
特点:
- 底层是哈希表
- 无序
- 允许
null key和null value - 线程不安全
示例:
java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
适用场景:
- 只关心快速存取
- 不关心遍历顺序
2. LinkedHashMap
你刚问到的这个。
特点:
- 基于
HashMap - 有顺序
- 默认保持插入顺序
- 也可以按访问顺序
- 线程不安全
示例:
java
Map<String, Integer> map = new LinkedHashMap<>();
适用场景:
- 需要稳定输出顺序
- 配置、缓存、文件读写回写
3. Hashtable
比较老的类。
特点:
- 线程安全(方法基本都
synchronized) - 不允许
null key和null value - 性能通常不如现代方案
- 现在一般不推荐新项目直接用
示例:
java
Map<String, Integer> map = new Hashtable<>();
适用场景:
- 主要是老代码兼容
- 现代项目通常用
ConcurrentHashMap替代
4. ConcurrentHashMap
并发环境最常见。
特点:
- 线程安全
- 性能比
Hashtable更好 - 不允许
null key和null value - 适合多线程读写
示例:
java
Map<String, Integer> map = new ConcurrentHashMap<>();
适用场景:
- 多线程共享缓存
- 并发统计
- 服务端程序
5. WeakHashMap
特殊用途。
特点:
- key 是弱引用
- 当 key 没有其他强引用时,可能被 GC 回收
- 常用于缓存
示例:
java
Map<Object, String> map = new WeakHashMap<>();
适用场景:
- 想让缓存条目在 key 不再使用时自动释放
6. IdentityHashMap
按"对象地址意义"比较,不按 equals() 比较。
特点:
- 比较 key 时用
== - 不是常规语义的 Map
- 很容易误用
示例:
java
Map<String, Integer> map = new IdentityHashMap<>();
比如:
java
String a = new String("x");
String b = new String("x");
在普通 HashMap 里,a 和 b 认为是同一个 key。
在 IdentityHashMap 里,它们不是同一个 key。
适用场景:
- 需要按对象身份区分,而不是按内容区分
7. EnumMap
严格说它不是 HashMap,但经常一起比较。
特点:
- key 必须是枚举类型
- 性能高,内存占用低
- 顺序通常按枚举定义顺序
示例:
java
enum Status { NEW, RUNNING, DONE }
Map<Status, String> map = new EnumMap<>(Status.class);
适用场景:
- key 是枚举时,优先考虑它,而不是
HashMap
8. TreeMap
也不是 HashMap,但也是常见 Map。
特点:
- 按 key 排序
- 底层是红黑树
- 查询/插入通常是
O(log n)
示例:
java
Map<String, Integer> map = new TreeMap<>();
适用场景:
- 需要排序后的 key
LinkedHashMap
LinkedHashMap 是 Java 集合框架中的一个 Map 实现类,它的核心特点是:
👉 既是 HashMap(基于哈希表),又能保持元素的顺序
java
Map<K, V> map = new LinkedHashMap<>();
本质上:
- 继承自
HashMap - 额外维护了一个双向链表
三、LinkedHashMap 的"顺序"是什么?
默认是:
👉 插入顺序(Insertion Order)
示例:
java
Map<String, Integer> map = new LinkedHashMap<>();
map.put("A", 1);
map.put("C", 3);
map.put("B", 2);
System.out.println(map);
输出:
text
{A=1, C=3, B=2}
👉 顺序就是你 put 的顺序
四、为什么它能保持顺序?
内部结构:
HashMap(快速查找)
+
双向链表(维护顺序)
每个节点类似:
text
[prev] ← node → [next]
所以:
- 查找:O(1)
- 遍历:按顺序走链表
九、回到你的代码为什么用它
java
Map<String, String> map = new LinkedHashMap<>();
👉 目的很明确:
-
保证:
- 读取文件 → 顺序不乱
- 写回文件 → 顺序一致
否则如果用 HashMap:
text
每次写出来顺序都可能不同 ❌