SparseArray
se puede usar para reemplazar HashMap
cuando la clave es un tipo primitivo. Existen algunas variantes para diferentes tipos de clave / valor, aunque no todas están disponibles públicamente.
Los beneficios son:
- Libre de asignación
- No boxeo
Inconvenientes:
- Generalmente más lento, no indicado para grandes colecciones
- No funcionarán en un proyecto que no sea Android
HashMap
puede ser reemplazado por lo siguiente:
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
En términos de memoria, aquí hay un ejemplo de SparseIntArray
vs HashMap<Integer, Integer>
para 1000 elementos:
SparseIntArray
:
class SparseIntArray {
int[] keys;
int[] values;
int size;
}
Clase = 12 + 3 * 4 = 24 bytes
Matriz = 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;
}
Clase = 12 + 8 * 4 = 48 bytes
Entrada = 32 + 16 + 16 = 64 bytes
Matriz = 20 + 1000 * 64 = 64024 bytes
Total = 64,136 bytes
Fuente: Android Memories por Romain Guy de la diapositiva 90.
Los números anteriores son la cantidad de memoria (en bytes) asignada en el montón por JVM. Pueden variar según la JVM específica utilizada.
El java.lang.instrument
paquete contiene algunos métodos útiles para operaciones avanzadas como verificar el tamaño de un objeto con getObjectSize(Object objectToSize)
.
Hay información adicional disponible en la documentación oficial de Oracle .
Clase = 12 bytes + (n variables de instancia) * 4 bytes
Matriz = 20 bytes + (n elementos) * (tamaño del elemento)
Entrada = 32 bytes + (tamaño del primer elemento) + (tamaño del segundo elemento)
Vine aquí solo queriendo un ejemplo de cómo usar
SparseArray
. Esta es una respuesta suplementaria para eso.Crear una matriz dispersa
A
SparseArray
asigna números enteros a algunosObject
, por lo que podría reemplazarlosString
en el ejemplo anterior con cualquier otroObject
. Si está asignando enteros a enteros, useSparseIntArray
.Agregar o actualizar elementos
Use
put
(oappend
) para agregar elementos a la matriz.Tenga en cuenta que las
int
claves no necesitan estar en orden. Esto también se puede usar para cambiar el valor en unaint
clave particular .Eliminar elementos
Use
remove
(odelete
) para eliminar elementos de la matriz.El
int
parámetro es la clave entera.Valores de búsqueda para una clave int
Use
get
para obtener el valor de alguna clave entera.Puede usarlo
get(int key, E valueIfKeyNotFound)
si desea evitarnull
las claves faltantes.Iterar sobre los artículos
Puede usar
keyAt
yvalueAt
algún índice para recorrer la colección porqueSparseArray
mantiene un índice separado distinto de lasint
claves.Tenga en cuenta que las claves se ordenan en valor ascendente, no en el orden en que se agregaron.
fuente
Es solo una advertencia de esta documentación de su matriz dispersa:
El
SparseArray
está hecho para ser eficiente de la memoria que el uso de la HashMap regular, que es no permitir que múltiples lagunas dentro de la matriz no como HashMap. No hay nada de qué preocuparse, puede usar el HashMap tradicional si no desea preocuparse por la asignación de memoria al dispositivo.fuente
SparseArray
evita que el entero clave sea Auto box, que es otra operación y rendimiento de costos. en lugar de Map, autoboxeará el entero primitivo paraInteger
Una matriz dispersa en Java es una estructura de datos que asigna claves a valores. La misma idea que un mapa, pero implementación diferente:
Un mapa se representa internamente como una matriz de listas, donde cada elemento en estas listas es un par clave, valor. Tanto la clave como el valor son instancias de objeto.
Una matriz dispersa se compone simplemente de dos matrices: una matriz de claves (primitivas) y una matriz de valores (objetos). Puede haber huecos en estos índices de matrices, de ahí el término matriz "dispersa".
El interés principal de SparseArray es que ahorra memoria al usar primitivas en lugar de objetos como clave.
fuente
Después de buscar en Google, trato de agregar información a las respuestas ya publicadas:
Isaac Taylor hizo una comparación de rendimiento para SparseArrays y Hashmaps. Él dice que
y
Una comparación en Edgblog muestra que un SparseArray necesita mucha menos memoria que un HashMap debido a la clave más pequeña (int vs Integer) y al hecho de que
Como conclusión, diría que la diferencia podría importar si va a almacenar una gran cantidad de datos en su Mapa. De lo contrario, simplemente ignore la advertencia.
fuente
Si, es correcto. Pero cuando solo tiene 10 o 20 elementos, la diferencia de rendimiento debe ser insignificante.
Creo que la mayoría de las veces solo usamos
HashMap
para buscar un valor asociado con una clave, mientras queSparseArray
es realmente bueno en esto.El código fuente de SparseArray es bastante simple y fácil de entender, de modo que solo paga poco esfuerzo al moverlo a otras plataformas (a través de una simple COPIAR y pegar).
Todo lo que puedo decir es, (a la mayoría de los desarrolladores) a quién le importa?
Otro aspecto importante
SparseArray
es que solo usa una matriz para almacenar todos los elementos mientras losHashMap
usaEntry
, por lo queSparseArray
cuesta significativamente menos memoria que aHashMap
, vea estofuente
Es lamentable que el compilador emita una advertencia. Supongo que HashMap ha sido usado en exceso para almacenar elementos.
Los SparseArrays tienen su lugar. Dado que usan un algoritmo de búsqueda binario para encontrar un valor en una matriz, debe considerar lo que está haciendo. La búsqueda binaria es O (log n) mientras que la búsqueda hash es O (1). Esto no significa necesariamente que la búsqueda binaria sea más lenta para un conjunto de datos dado. Sin embargo, a medida que aumenta el número de entradas, el poder de la tabla hash se hace cargo. De ahí los comentarios en los que un número bajo de entradas puede ser igual y posiblemente mejor que usar un HashMap.
Un HashMap es tan bueno como el hash y también puede verse afectado por el factor de carga (creo que en versiones posteriores ignoran el factor de carga para que pueda optimizarse mejor). También agregaron un hash secundario para asegurarse de que el hash sea bueno. También la razón por la que SparseArray funciona realmente bien para relativamente pocas entradas (<100).
Sugeriría que si necesita una tabla hash y desea un mejor uso de la memoria para un entero primitivo (sin boxeo automático), etc., pruebe tesoro. ( http://trove.starlight-systems.com - licencia LGPL). (Sin afiliación a trove, al igual que su biblioteca)
Con el edificio simplificado multi-dex que tenemos, ni siquiera necesita reempacar el tesoro para lo que necesita. (el tesoro tiene muchas clases)
fuente