使用SparseIntArray代替HashMap <integer,integer =“”> with putSerializable </integer,>

时间:2013-06-13 02:49:39

标签: java android

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

Use new SparseIntArray(...) for better performance

现在问题是SparseIntArray()没有实现Serializable界面,并且无法与getSerializable()中的putSerializable()onRestoreInstanceState()一起使用。< / p>

  1. 使用SparseIntArray()代替HashMap<Integer, Integer>有多重要?

  2. 我应该解决使SparseIntArray可序列化的麻烦吗? (我的第一个想法是创建一个实现Serializable的包装器类,这是正确的方法吗?)

2 个答案:

答案 0 :(得分:27)

  

1)使用SparseIntArray代替HashMap

有多重要?

这取决于你如何使用它。但除非你试图代表这样的许多和/或大型“阵列”,否则差异不太可能显着。

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

  

2)我应该解决使SparseIntArray可序列化的麻烦吗? (我的第一个想法是创建一个实现Serializable的包装类,这是正确的方法吗?)

见上文及以下。

实现包装听起来合理......如果你需要解决这个问题。另一种方法可能是声明SparseIntArray的可序列化子类。建议使用自定义readObjectwriteObject方法。


SparseIntArray类(source code)使用一对int数组来表示映射中的键和值,并使用二进制搜索进行查找。按键保持顺序没有“孔”,并使用二进制搜索执行查找。这意味着以下内容:

  • SparseIntArray的内存使用量大约相当于同等HashMap的10倍。这是由于各种因素的结合:

    • 哈希表数组每个条目大约保留1个引用(取决于表的填充程度......),

    • 键和值必须在Integer中作为HashMap个对象“加框”,并且

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

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

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

  • 查询(即getO(logN)O(1)的{​​{1}}进行比较。

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

  • 顺序插入(即以按键顺序递增)为HashMap

所以“哪个最好”显然取决于你所优化的内容,你如何使用数据结构,以及它将会有多大。

答案 1 :(得分:5)

使用HashMap<Integer, Integer>的问题是每个键和值都需要加框。这种影响的范围可以是从大量垃圾生成和/或内存使用到系统的重负荷(更不用说装箱/拆箱值的轻微性能损失)。 (这些担忧也推动了几个第三方collection frameworks for primitives的发展。)

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