使用SparseIntArray代替HashMap<Integer,Integer>与putSerializable

2022-09-04 06:32:50

当我在Android中使用带有键和数据值的a时,我在Eclipse中收到以下消息:HashMapInteger

Use new SparseIntArray(...) for better performance

现在的问题是没有实现接口,不能与 和 在 中使用。SparseIntArray()SerializablegetSerializable()putSerializable()onRestoreInstanceState()

  1. 使用 代替 ?SparseIntArray()HashMap<Integer, Integer>

  2. 我应该经历可序列化的麻烦吗?(我的第一个想法是制作一个实现的包装类,这是正确的方法吗?SparseIntArraySerializable


答案 1

1) 使用代替 ?SparseIntArrayHashMap

这取决于你如何使用它。但是,除非您尝试像这样表示许多和/或大型“数组”,否则差异不太可能很大。

请注意,Java SE 没有任何稀疏数组类,这通常不是问题。

2)我应该经历可序列化的麻烦吗?(我的第一个想法是制作一个实现的包装类,这是正确的方法吗?SparseIntArraySerializable

见上文和下文。

实现包装器听起来很合理...如果你需要去这个麻烦。另一种方法可能是声明 的可序列化子类。建议声明自定义和方法。SparseIntArrayreadObjectwriteObject


该类(源代码)使用一对数组来表示映射中的键和值,并使用二进制搜索来执行查找。密钥按顺序保存,没有“孔”,并使用二进制搜索执行查找。这意味着:SparseIntArrayint

  • 的内存使用量大约比等效的 少 10 倍。这是由于以下因素的组合:SparseIntArrayHashMap

    • 哈希表数组每个条目大约包含 1 个引用(取决于表的满度 ...),

    • 键和值必须作为 对象“装箱”,并且IntegerHashMap

    • 中的每个条目都需要一个相当重的“节点”对象 - 标准实现中的4个字段。HashMap

    (但是,如果以正确的方式创建对象,则类实例缓存的影响可以减轻“装箱”开销。IntegerInteger

    相比之下,稀疏版本需要 4 个字节的单词。2 * capacity

  • 查找(即 )与 .getO(logN)O(1)HashMap

  • 随机插入与 的比较。(这是因为插入必须平均移动现有条目的一半,以便可以在数组中的正确位置添加新条目。O(N)O(1)HashMap

  • 顺序插入(即按键顺序升序)是 。O(1)

因此,“哪个是最好的”显然取决于你正在优化什么,你如何使用数据结构,以及它将变得多大。


答案 2

使用 a 的问题在于每个键和值都需要装箱。其影响范围可以从没有到大量垃圾生成和/或内存使用对系统的重负载(更不用说装箱/拆箱值的轻微性能损失)。(这些担忧也推动了几个用于原语的第三方集合框架的开发。HashMap<Integer, Integer>

如果你认为的好处是值得的,那么我认为你的包装类方法是合理的。另一种方法是让它实现,这也可以用来保存/恢复实例状态。SparseIntArrayParcelable


推荐