三者都是线程不安全的。
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
⚠️ 注意事项
- SparseArray不是Map接口的实现,API略有不同
- ArrayMap和SparseArray都不是线程安全的,多线程需自行同步
- Android 12+ 系统对ArrayMap有更多内部优化
- 数据量临界点:建议实际测试,一般500-1000条是分界线