java中的map大总结

301 阅读3分钟

在Java中,Map 接口是用于存储键值对(Key-Value)的数据结构,常见的实现类有以下几种,它们各自有不同的特性和适用场景:


1. HashMap

  • 实现原理:基于哈希表(数组 + 链表/红黑树),使用键的哈希值来存储数据。
  • 特点
    • 允许 null 作为键和值。
    • 无序,不保证插入顺序或键的排序。
    • 线程不安全(非同步)。
  • 性能:查找、插入、删除操作的时间复杂度接近 O(1)
  • 适用场景:大多数键值对存储需求,不需要顺序或线程安全时首选。
  • 注意:Java 8后,当链表长度超过阈值(默认8)时,链表会转为红黑树以优化性能。

2. LinkedHashMap

  • 实现原理:继承自 HashMap,在哈希表的基础上维护了一个双向链表
  • 特点
    • 保持键的插入顺序访问顺序(LRU顺序)。
    • 线程不安全
  • 适用场景:需要保持插入顺序或实现LRU缓存(通过构造函数设置访问顺序)。
  • 示例
    Map<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true); // 访问顺序
    

3. TreeMap

  • 实现原理:基于红黑树(自平衡二叉搜索树)。
  • 特点
    • 键按自然顺序或自定义比较器(Comparator)排序。
    • 支持范围查询(如 subMap(), firstKey(), lastKey())。
    • 线程不安全
  • 性能:查找、插入、删除的时间复杂度为 O(log n)
  • 适用场景:需要有序键的场景,如按排序遍历键值对。

4. ConcurrentHashMap

  • 实现原理:分段锁(Java 7)或 CAS + 细粒度锁(Java 8+),支持高并发。
  • 特点
    • 线程安全,但比 Hashtable 性能更高。
    • 不允许 null 作为键或值。
    • 分段锁设计减少锁竞争。
  • 适用场景:多线程环境下的高并发操作。

5. Hashtable

  • 实现原理:早期基于同步方法的哈希表。
  • 特点
    • 线程安全(所有方法加锁),但性能较差。
    • 不允许 null 键或值。
  • 缺点:已过时,推荐用 ConcurrentHashMap 替代。

6. WeakHashMap

  • 实现原理:键是弱引用(Weak Reference),当键不再被强引用时,条目会被自动回收。
  • 适用场景:缓存实现(如临时缓存数据,避免内存泄漏)。

7. EnumMap

  • 实现原理:专为枚举类型设计的紧凑数组。
  • 特点
    • 键必须是枚举类型。
    • 内部用数组存储,性能极高。
    • 按枚举定义的顺序排序。
  • 适用场景:键为枚举类型的场景。

8. IdentityHashMap

  • 实现原理:使用 == 代替 equals() 比较键的相等性。
  • 特点
    • 键的相等性基于对象地址(内存地址),而非值。
  • 适用场景:需要区分对象实例的场景(如序列化、深拷贝)。

9. Properties

  • 实现原理:继承自 Hashtable,键值均为字符串。
  • 特点
    • 用于读取配置文件(.properties 文件)。
    • 提供 load()store() 方法操作文件。
  • 适用场景:配置文件管理。

总结表格

Map实现类线程安全有序性允许Null键性能适用场景
HashMap无序O(1)通用存储
LinkedHashMap插入/访问顺序O(1)保持顺序或LRU缓存
TreeMap自然/自定义O(log n)有序键操作
ConcurrentHashMap无序O(1)高并发环境
Hashtable无序O(1)过时,不推荐使用
WeakHashMap无序O(1)弱引用缓存
EnumMap枚举定义顺序O(1)枚举键的高效存储
IdentityHashMap无序O(1)对象地址比较

选择建议:

  • 默认选择HashMap(不需要顺序)或 LinkedHashMap(需要插入顺序)。
  • 高并发ConcurrentHashMap
  • 有序键TreeMap
  • 枚举键EnumMap