SparseArray vs HashMap [英] SparseArray vs HashMap

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

问题描述

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


  1. SparseArray 的Android文档显示它通常比传统的 HashMap

  2. $ c> SparseArray 您的代码可以与其他Map实现一起使用,并且您可以使用为Maps设计的所有Java API。
  3. 如果您使用 HashMap s而不是 SparseArray 来编写代码,您的代码可以在非android项目中使用。 b $ b
  4. 映射覆盖 equals() hashCode(),而 SparseArray 不会。

然而每当我尝试使用 HashMap 在Android项目中使用整数键,IntelliJ告诉我应该使用 SparseArray 来代替。我觉得这很难理解。有没有人知道使用 SparseArray s?

解决方案

< a href =https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util/SparseArray.java =nofollow noreferrer> SparseArray 可用于替换 HashMap 当键是基本类型时。
尽管不是所有的键都可以公开获得,但是对于不同的键/值类型有一些变体。



好处是:


  • 无分配

  • 无装箱



缺点:$ b​​
$ b

  • 一般较慢,不适用于大集合

  • 在非Android项目中工作



HashMap可以替换为以下内容:

  SparseArray< Integer,Object> 
SparseBooleanArray< Integer,Boolean>
SparseIntArray< Integer,Integer>
SparseLongArray< Integer,Long>
LongSparseArray< Long,Object>
LongSparseLongArray< Long,Long> //这不是公共类
//但可以从Android源代码复制

在内存方面,这里是一个SparseIntArray和HashMap的1000个元素的示例



SparseIntArray:

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

Class = 12 + 3 * 4 = 24字节

Array = 20 + 1000 * 4 = 4024 bytes
Total = 8,072 bytes


HashMap: p>

  class HashMap< K,V> {
条目< K,V> []表;
条目< K,V> forNull;
int size;
int modCount;
int闽值;
Set< K>键
Set< Entry< K,V>>项;
Collection< V>值;
}

Class = 12 + 8 * 4 = 48字节

Entry = 32 + 16 + 16 = 64 bytes
Array = 20 + 1000 * 64 = 64024 bytes
Total = 64,136 bytes



资料来源: Romain Guy的Android Memories 从幻灯片90开始。

以上数字是JVM在堆上分配的内存量(以字节为单位)。
它们可能会有所不同,具体取决于所使用的特定JVM。



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

其他信息可从官方 $ {

b $ b Array = 20字节+(n个元素)*(元素大小)

Entry = 32字节+(第一元素大小)+(2ns元素大小)

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

  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.

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 can be used to replace HashMap when the key is a primitive type. There are some variants for different key/value type even though not all of them are publicly available.

Benefits are:

  • Allocation-free
  • No boxing

Drawbacks:

  • Generally slower, not indicated for large collections
  • They won't work in non-android project

HashMap can be replaced by the followings:

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 

In terms of memory here is an example of SparseIntArray vs HashMap for 1000 elements

SparseIntArray:

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

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;
}

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

Source: Android Memories by Romain Guy from slide 90.

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 package contains some helpful methods for advanced operation like checking the size of an object with getObjectSize(Object objectToSize).

Extra info are available from official Oracle documentation

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

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

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