SparseArray 与 HashMap [英] SparseArray vs HashMap

查看:24
本文介绍了SparseArray 与 HashMap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能想到为什么带有整数键的 HashMaps 比 SparseArrays 好很多的几个原因:

I can think of several reasons why HashMaps with integer keys are much better than SparseArrays:

  1. SparseArray 的 Android 文档说它通常比传统的 HashMap 慢".
  2. 如果您使用 HashMaps 而不是 SparseArrays 编写代码,您的代码将与 Map 的其他实现一起使用,并且您将能够使用设计的所有 Java API用于地图.
  3. 如果您使用 HashMaps 而不是 SparseArrays 编写代码,您的代码将可以在非 Android 项目中运行.
  4. Map 会覆盖 equals()hashCode()SparseArray 不会.
  1. The Android documentation for a SparseArray says "It is generally slower than a traditional HashMap".
  2. If you write code using HashMaps rather than SparseArrays your code will work with other implementations of Map and you will be able to use all of the Java APIs designed for Maps.
  3. If you write code using HashMaps rather than SparseArrays your code will work in non-android projects.
  4. Map overrides equals() and hashCode() whereas SparseArray doesn't.

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

Yet whenever I try to use a HashMap with integer keys in an Android project, IntelliJ tells me I should use a SparseArray instead. I find this really difficult to understand. Does anyone know any compelling reasons for using SparseArrays?

推荐答案

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

SparseArray can be used to replace HashMap when the key is a primitive type. There are some variants for different key/value types, even though not all of them are publicly available.

好处是:

  • 免分配
  • 没有拳击

缺点:

  • 通常较慢,不适用于大型集合
  • 它们不适用于非 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 

在内存方面,这里是一个 SparseIntArray vs HashMap 的例子:1000 个元素:

In terms of memory, here is an example of SparseIntArray vs HashMap<Integer, Integer> for 1000 elements:

SparseIntArray:

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

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

Class = 12 + 3 * 4 = 24 bytes
Array = 20 + 1000 * 4 = 4024 bytes
Total = 8,072 bytes

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

Class = 12 + 8 * 4 = 48 bytes
Entry = 32 + 16 + 16 = 64 bytes
Array = 20 + 1000 * 64 = 64024 bytes
Total = 64,136 bytes

来源:Android Memories by Romain Guy,来自幻灯片 90.

Source: Android Memories by Romain Guy from slide 90.

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

The numbers above are the amount of memory (in bytes) allocated on heap by JVM. They may vary depending on the specific JVM used.

java.lang.instrument 包包含一些有用的高级操作方法,例如使用 getObjectSize(Object objectToSize) 检查对象的大小.

The java.lang.instrument package contains some helpful methods for advanced operations like checking the size of an object with getObjectSize(Object objectToSize).

更多信息可从官方 Oracle文档.

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

Class = 12 bytes + (n instance variables) * 4 bytes
Array = 20 bytes + (n elements) * (element size)
Entry = 32 bytes + (1st element size) + (2nd element size)

这篇关于SparseArray 与 HashMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆