13

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

Use new SparseIntArray(...) for better performance

现在的问题是它SparseIntArray()没有实现Serializable接口,不能getSerializable()putSerializable()in一起使用onRestoreInstanceState()

  1. SparseIntArray()使用而不是使用有多重要HashMap<Integer, Integer>

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

4

2 回答 2

27

SparseIntArray1)使用而不是使用有多重要HashMap

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

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

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

见上,下。

实现包装器听起来很合理......如果你需要解决这个问题。另一种方法可能是声明SparseIntArray. 建议声明自定义readObjectwriteObject方法。


该类SparseIntArray源代码)使用一对int数组来表示映射中的键和值,并使用二分查找进行查找。键保持有序,没有“漏洞”,并使用二进制搜索执行查找。这意味着以下内容:

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

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

    • 键和值必须“装箱”为a 中Integer的对象HashMap,并且

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

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

    相比之下,稀疏版本需要2 * capacity4 个字节的字。

  • 查找 (ie get)O(logN)O(1)a 进行比较HashMap

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

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

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

于 2013-06-13T02:56:36.027 回答
5

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

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

于 2013-06-13T02:56:45.520 回答