Java选Map需据场景:单线程高频读写用HashMap;需顺序遍历选LinkedHashMap(插入/访问序)或TreeMap(按键排序);多线程优先ConcurrentHashMap;特殊需求如引用相等、弱引用缓存、枚举键分别用IdentityHashMap、WeakHashMap、EnumMap。

Java里选Map,关键看场景:要线程安全?要排序?要高性能?还是得支持null键值?不同实现差异大,选错可能拖慢性能甚至出bug。
查得快、写得快:优先考虑HashMap
绝大多数场景下,HashMap 是默认首选。它基于哈希表,平均时间复杂度 O(1),支持 null 键和 null 值。但不保证顺序,也不支持并发写入。
- 适合单线程、对顺序无要求、频繁读写的场景(比如缓存、临时映射)
- 注意初始容量和加载因子:如果预估数据量大,建议指定初始容量(如
new HashMap(128)),避免多次扩容影响性能 - 键对象必须正确重写
hashCode()和equals()
需要有序遍历:用LinkedHashMap或TreeMap
LinkedHashMap 按插入顺序(或访问顺序)维护元素,遍历时保持稳定顺序,开销略高于 HashMap,但远低于 TreeMap。
- 适合需按插入顺序处理的场景(如最近使用记录、日志缓冲)
- 开启访问顺序(
new LinkedHashMap(16, 0.75f, true))可实现 LRU 缓存逻辑
TreeMap 基于红黑树,天然按键排序,支持范围查询(subMap、headMap),但增删查都是 O(log n)。
立即学习“Java免费学习笔记(深入)”;
- 适合需要自动排序、区间查找或键是自定义类型且已实现
Comparable或传入Comparator - 不支持 null 键(会抛
NullPointerException),null 值可以
多线程环境:别直接用HashMap,考虑ConcurrentHashMap或Collections.synchronizedMap
ConcurrentHashMap 是高并发下的推荐选择。它分段锁(JDK 8+ 改为 CAS + synchronized),读操作无锁,写操作粒度更细,性能远超同步包装类。
- 适合读多写少、多线程共享且需高吞吐的场景(如配置中心、共享计数器)
- 不支持 null 键和 null 值(否则抛
NullPointerException) - 迭代器弱一致性:不抛
ConcurrentModificationException,但可能看不到最新修改
Collections.synchronizedMap 简单粗暴,所有方法加同一把锁,适合并发不高、代码简单、兼容老版本的场景。
- 注意:即使包装了,遍历仍需手动同步(
synchronized(map) { ... }) - 一般不推荐用于新项目
特殊需求:IdentityHashMap、WeakHashMap、EnumMap
IdentityHashMap 用 == 比较键,而非 equals(),适合需要“引用相等”的场景(如序列化框架、代理对象管理)。
WeakHashMap 的键是弱引用,当键无其他强引用时,GC 可回收该键值对。适合构建内存敏感的缓存(如监听器注册表)。
EnumMap 专为枚举类型设计,内部用数组实现,性能极佳,且不接受 null 键(枚举本身不能为 null)。
- 键只能是枚举类型,创建时需指定枚举类:
new EnumMap(Color.class) - 比 HashMap 存储更紧凑,访问更快
Map选型不是死记硬背,而是结合数据特征、并发模型、顺序要求和生命周期来判断。先想清楚“我到底要什么”,再挑最贴合的那个实现。










