小编典典

SparseArray 与 HashMap

all

我可以想到几个为什么HashMap带整数键的 s 比 s 好得多的原因SparseArray

  1. a 的 Android 文档SparseArray说“它通常比传统的慢HashMap”。
  2. 如果您使用HashMaps 而不是SparseArrays 编写代码,您的代码将与 Map 的其他实现一起使用,并且您将能够使用为 Maps 设计的所有 Java API。
  3. 如果您使用HashMaps 而不是SparseArrays 编写代码,您的代码将在非 android 项目中工作。
  4. 地图覆盖equals()hashCode()SparseArray没有。

然而,每当我尝试HashMap在 Android 项目中使用带有整数键的 a 时,IntelliJ 都会告诉我应该使用
aSparseArray来代替。我觉得这真的很难理解。有谁知道使用SparseArrays 的任何令人信服的理由?


阅读 66

收藏
2022-07-13

共1个答案

小编典典

SparseArrayHashMap当键是原始类型时,可用于替换。不同的键/值类型有一些变体,尽管并非所有变体都是公开可用的。

好处是:

  • 免分配
  • 没有拳击

缺点:

  • 通常较慢,不适用于大型集合
  • 它们不适用于非 Android 项目

HashMap可以替换为以下内容:

SparseArray          <Integer, Object>
SparseBooleanArray   <Integer, Boolean>
SparseIntArray       <Integer, Integer>
SparseLongArray      <Integer, Long>
LongSparseArray      <Long, Object>
LongSparseLongArray  <Long, Long>   //this is not a public class                                 
                                    //but can be copied from  Android source code

在内存方面,这里是1000 个元素的SparseIntArrayvs示例:HashMap<Integer, Integer>

SparseIntArray

class SparseIntArray {
    int[] keys;
    int[] values;
    int size;
}

类 = 12 + 3 * 4 = 24 字节
数组 = 20 + 1000 * 4 = 4024 字节
总计 = 8,072 字节

HashMap

class HashMap<K, V> {
    Entry<K, V>[] table;
    Entry<K, V> forNull;
    int size;
    int modCount;
    int threshold;
    Set<K> keys
    Set<Entry<K, V>> entries;
    Collection<V> values;
}

类 = 12 + 8 * 4 = 48 字节
条目 = 32 + 16 + 16 = 64 字节
数组 = 20 + 1000 * 64 = 64024 字节
总计 = 64,136 字节

资料来源:来自幻灯片 90的 Romain Guy 的 Android Memories

上面的数字是 JVM 在堆上分配的内存量(以字节为单位)。它们可能因使用的特定 JVM 而异。

java.lang.instrument包包含一些用于高级操作的有用方法,例如使用getObjectSize(Object objectToSize).

额外信息可从官方Oracle
文档
中获得。

类 = 12 字节 +(n 个实例变量) 4 字节
数组 = 20 字节 +(n 个元素)
(元素大小)
条目 = 32 字节 +(第一个元素大小)+(第二个元素大小)

2022-07-13