HashMap、ArrayMap、SparseArray

3 阅读1分钟

三者都是线程不安全的。

ArrayMap、SparseArray 是Android专属的

三种数据结构对比总览

特性

HashMap

ArrayMap

SparseArray

底层结构

哈希表+链表/红黑树

有序数组+二分查找

两个有序数组(int键+Object值)

Key类型

Object

Object

仅支持int

时间复杂度(查)

O(1)

O(log n)

O(log n)

时间复杂度(增)

O(1)

O(n)

O(n)

内存占用

较高

较低

最低

线程安全

Android专属

否(Java标准)

1️⃣ HashMap

优点:

  • 查询性能最优:平均O(1)时间复杂度

  • 通用性强:Java标准库,任何Java/Kotlin环境可用

  • Key类型灵活:支持任何Object类型作为键

  • 容量大:适合存储大量数据

缺点:

  • 内存开销大:每个Entry对象有额外开销,存在哈希冲突时的链表/树节点

  • 自动扩容成本:容量不足时重新哈希开销较大

  • Android特定优化少:没有针对移动设备内存优化

最佳使用场景

// 适合:数据量大、频繁查询、Key类型多样
val userMap = HashMap<String, User>()  // 用户信息缓存
val configMap = HashMap<String, Any>()  // 配置信息
  • 数据量 > 1000条

  • 需要频繁增删查操作

  • Key类型不是int或不确定

  • 对内存不敏感的场景

2️⃣ ArrayMap

✅ 优点

  • 内存优化:比HashMap节省约30-50%内存
  • Android专属优化:专为移动设备设计
  • 有序存储:按键的哈希值排序,可预测遍历顺序
  • 小数据量性能好:数据少时二分查找很快

❌ 缺点

  • 增删较慢:数组插入删除需要移动元素,O(n)
  • 数据量大时性能下降:超过1000条后性能明显不如HashMap
  • 扩容成本高:数组复制开销

🎯 最佳使用场景

// 适合:数据量中等、内存敏感、Key类型多样
val arrayMap = ArrayMap<String, Int>()  // 轻量级缓存
val bundleMap = ArrayMap<String, Parcelable>()  // Bundle内部使用
  • 数据量 100 ~ 1000条
  • 内存敏感场景(如手持设备)
  • Key类型不是int
  • 读多写少的场景

3️⃣ SparseArray

✅ 优点

  • 内存最省:无Entry对象,两个数组直接存储,比HashMap节省约50-70%内存
  • 无自动装箱:int键无需装箱为Integer,减少GC压力
  • Android专属优化:系统内部大量使用
  • 遍历高效:可直接通过索引访问

❌ 缺点

  • Key类型受限仅支持int类型
  • 增删最慢:数组移动+二分查找,O(n)
  • 数据量大性能差:超过1000条后性能显著下降

🎯 最佳使用场景

kotlin

编辑

1// 适合:int键、数据量小、内存极度敏感
2val sparseArray = SparseArray<View>()  // View存储
3val stateMap = SparseArray<State>()  // 状态机
  • 数据量 < 1000条(最佳<500)
  • Key必须是int
  • 内存极度敏感场景
  • 读多写少,增删不频繁

📈 性能对比图示

内存占用:  SparseArray < ArrayMap < HashMap
           (最优)                    (最高)

查询性能:  HashMap > ArrayMap  SparseArray
           (最优)                   (相当)

增删性能:  HashMap > ArrayMap > SparseArray
           (最优)                   (最慢)

适用数据量:
  HashMap:    1000+ 
  ArrayMap:   100 ~ 1000 
  SparseArray: < 1000  (int键)

🎯 实际选择建议

// 场景1: 用户ID(int) → 用户对象,数据量约200条
val userCache = SparseArray<User>()  // ✅ 最佳选择

// 场景2: 字符串Key → 配置值,数据量约500条
val config = ArrayMap<String, Any>()  // ✅ 内存友好

// 场景3: 复杂Key → 数据,数据量5000+条
val dataMap = HashMap<ComplexKey, Data>()  // ✅ 性能优先

// 场景4: Android Bundle传递数据
val bundle = Bundle()  // 内部使用ArrayMap

⚠️ 注意事项

  1. SparseArray不是Map接口的实现,API略有不同
  2. ArrayMap和SparseArray都不是线程安全的,多线程需自行同步
  3. Android 12+ 系统对ArrayMap有更多内部优化
  4. 数据量临界点:建议实际测试,一般500-1000条是分界线