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