【问题标题】:Using SparseIntArray instead of HashMap <Integer, Integer> with putSerializable使用 SparseIntArray 而不是 HashMap <Integer, Integer> 和 putSerializable
【发布时间】:2013-06-09 07:50:22
【问题描述】:

当我在 Android 中使用 HashMapInteger 键和数据值时,我在 Eclipse 中收到此消息:

Use new SparseIntArray(...) for better performance

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

  1. 使用SparseIntArray() 而不是HashMap&lt;Integer, Integer&gt; 有多重要?

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

【问题讨论】:

    标签: java android


    【解决方案1】:

    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 字节字。

    • 查找(即get)是O(logN),而O(1)则是HashMap

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

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

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

    【讨论】:

      【解决方案2】:

      使用HashMap&lt;Integer, Integer&gt; 的问题是每个键和值都需要装箱。这种影响的范围从没有到大量垃圾生成和/或内存使用对系统造成沉重负载(更不用说装箱/拆箱值的轻微性能损失)。 (这些担忧也推动了几个第三方collection frameworks for primitives的开发。)

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-13
        • 2015-02-19
        • 1970-01-01
        • 2015-06-18
        • 1970-01-01
        相关资源
        最近更新 更多