Android | 为什么有了ArrayMap还要再设计SparseArray?

两者区别:Key的类型

  • ArrayMap:通用Key类型
kotlin 复制代码
// ArrayMap - 支持任何Object作为Key
val arrayMap = ArrayMap<String, Any>()
arrayMap.put("name", "Alice")
arrayMap.put("age", 25)

val arrayMap2 = ArrayMap<Any, Any>()
arrayMap2.put(CustomObject(), "value")
  • SparseArray:专用 int Key 类型
kotlin 复制代码
// SparseArray - 只支持int作为Key
val sparseArray = SparseArray<String>()
sparseArray.put(100, "Alice")  // Key 必须是 int
sparseArray.put(200, "Bob")

// 变种版本
val sparseIntArray = SparseIntArray()
sparseIntArray.put(100, 25)    // Key=int, Value=int

为什么需要SparseArray?

1. 避免自动装箱

ArrayMap 的存储方式:

vbnet 复制代码
mHashes: [hash("100"), hash("200")]  // String 的哈希值
mArray:  ["100", "Alice", "200", "Bob"]  // Key 被存储为 String 对象

SparseArray 的存储方式:

arduino 复制代码
mKeys:   [100, 200]           // 直接存储原始 int
mValues: ["Alice", "Bob"]     // 值数组

性能对比:

kotlin 复制代码
// ArrayMap - 需要自动装箱
val arrayMap = ArrayMap<Any, Any>()
arrayMap.put(100, "value")  // 发生装箱:int → Integer
val value = arrayMap.get(100) // 可能发生拆箱

// SparseArray - 无装箱开销
val sparseArray = SparseArray<String>()
sparseArray.put(100, "value")  // 直接存储原始 int
val value = sparseArray.get(100) // 直接使用原始 int

2. 内存优化

SparseArray 系列专门优化:

kotlin 复制代码
// 不同的原始值类型,避免任何装箱
SparseIntArray()      // int → int
SparseLongArray()     // int → long  
SparseBooleanArray()  // int → boolean
SparseArray<String>() // int → String (只有值可能装箱)

3. 更简单的哈希计算

ArrayMap:

java 复制代码
// 需要计算任意对象的 hashCode
int hash = key.hashCode();
// 可能处理哈希冲突

SparseArray:

java 复制代码
// 直接使用 int 值本身,无需计算哈希
int key = 100; // 这就是"哈希值"
// 不会有哈希冲突(除非相同的 key)

实际使用场景对比

  • 适合 SparseArray 的场景:
kotlin 复制代码
// 1. View的ID映射
val viewMap = SparseArray<View>()
viewMap.put(R.id.button_submit, submitButton)
viewMap.put(R.id.text_title, titleView)

// 2. 位置索引映射
val itemMap = SparseArray<ListItem>()
itemMap.put(0, headerItem)
itemMap.put(5, specialItem)
  • 适合 ArrayMap 的场景:
kotlin 复制代码
// 1. 字符串键的配置
val config = ArrayMap<String, Any>()
config.put("server_url", "https://api.example.com")
config.put("timeout", 5000)

// 2. Bundle 数据存储
val bundleData = ArrayMap<String, Any?>()

// 3. 任意对象键的映射
val objectMap = ArrayMap<Any, String>()

性能对比总结

方面 SparseArray ArrayMap HashMap
int Key 内存 最优 ❌ 需要装箱 ❌ 需要装箱
Object Key 支持 ❌ 不支持 ✅ 支持 ✅ 支持
查找性能 ✅ O(log n) ✅ O(log n) ✅ O(1)
插入性能 ⚠️ O(n) ⚠️ O(n) ✅ O(1)
内存占用 最低 ✅ 较低 ❌ 较高
  • SparseArray :为 int → Object 这种特定场景提供优化
  • ArrayMap :为通用的 Object → Object 映射提供平衡优化
  • HashMap :为大数据量高性能场景提供通用解决方案
相关推荐
心中有国也有家7 小时前
AtomGit Flutter 鸿蒙客户端:Canvas 绘制进阶-路径、渐变与混合模式
android·javascript·flutter·华为·harmonyos
hunterandroid8 小时前
WorkManager 可靠性实战:唯一任务、重试与幂等设计
android·前端
程序员老刘8 小时前
Android 17的10个AI功能,国内用户真正能用的有几个?
android·flutter·ai编程
花开彼岸天~9 小时前
鸿蒙应用开发实战【94】— 实战多卡号场景管理最佳实践
android·华为·harmonyos·鸿蒙系统
用户41659673693559 小时前
视频源文件音频轨异常分析记录
android
雨白12 小时前
嵌套 ScrollView 滑动冲突实战:实现内部优先滚动
android
阿pin12 小时前
Android随笔-IntentService详解(了解)
android·intentservice
海天鹰13 小时前
content://com.android.externalstorage.documents/document/primary%3A
android
阿pin14 小时前
Android随笔-WorkManager 与 AlarmManager
android·alarmmanager·workmanager
帅帅的记忆14 小时前
uniapp项目调用原生android studio的sdk文件(即aar文件)
android·uni-app·android studio