SparseArray
pode ser usado para substituir HashMap
quando a chave é do tipo primitivo. Existem algumas variantes para diferentes tipos de chave / valor, mesmo que nem todas elas estejam disponíveis publicamente.
Os benefícios são:
- Livre de alocação
- Sem boxe
Desvantagens:
- Geralmente mais lento, não indicado para coleções grandes
- Eles não funcionarão em um projeto que não seja Android
HashMap
pode ser substituído pelo seguinte:
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
Em termos de memória, aqui está um exemplo de SparseIntArray
vs HashMap<Integer, Integer>
para 1000 elementos:
SparseIntArray
:
class SparseIntArray {
int[] keys;
int[] values;
int size;
}
Classe = 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;
}
Classe = 12 + 8 * 4 = 48 bytes
Entrada = 32 + 16 + 16 = 64 bytes
Matriz = 20 + 1000 * 64 = 64024 bytes
Total = 64.136 bytes
Fonte: Memórias Android de Romain Guy, do slide 90.
Os números acima são a quantidade de memória (em bytes) alocada no heap pela JVM. Eles podem variar dependendo da JVM específica usada.
O java.lang.instrument
pacote contém alguns métodos úteis para operações avançadas, como verificar o tamanho de um objeto getObjectSize(Object objectToSize)
.
Informações adicionais estão disponíveis na documentação oficial do Oracle .
Classe = 12 bytes + (n variáveis de instância) * 4 bytes
Matriz = 20 bytes + (n elementos) * (tamanho do elemento)
Entrada = 32 bytes + (tamanho do 1º elemento) + (tamanho do segundo elemento)