SparseArray
может использоваться для замены, HashMap
когда ключ является примитивным типом. Есть несколько вариантов для различных типов ключ / значение, хотя не все они являются общедоступными.
Преимущества:
- Выделение свободных
- Нет бокса
Недостатки:
- Как правило, медленнее, не указывается для больших коллекций
- Они не будут работать в не 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
против HashMap<Integer, Integer>
1000 элементов:
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 байтов.
Источник: Android-воспоминания Ромена Гая со слайда 90.
Числа выше - это объем памяти (в байтах), выделенной в куче JVM. Они могут варьироваться в зависимости от конкретной используемой JVM.
java.lang.instrument
Пакет содержит некоторые полезные методы для сложных операций , таких как проверка размеров объекта с getObjectSize(Object objectToSize)
.
Дополнительная информация доступна из официальной документации Oracle .
Класс = 12 байтов + (n переменных экземпляра) * 4 байта
Массив = 20 байтов + (n элементов) * (размер элемента)
Запись = 32 байта + (размер 1-го элемента) + (размер 2-го элемента)
Я пришел сюда просто, чтобы получить пример использования
SparseArray
. Это дополнительный ответ для этого.Создать SparseArray
A
SparseArray
отображает целые числа на некоторыеObject
, так что вы можете заменитьString
в приведенном выше примере на любой другойObject
. Если вы отображаете целые числа в целые числа, используйтеSparseIntArray
.Добавить или обновить элементы
Используйте
put
(илиappend
) для добавления элементов в массив.Обратите внимание, что
int
ключи не должны быть в порядке. Это также может быть использовано для изменения значения в конкретномint
ключе.Удалить предметы
Используйте
remove
(илиdelete
) для удаления элементов из массива.int
Параметр является ключевым целым числом.Поиск значений для ключа int
Используйте,
get
чтобы получить значение для некоторого целочисленного ключа.Вы можете использовать,
get(int key, E valueIfKeyNotFound)
если хотите избежатьnull
пропавших ключей.Перебирать предметы
Вы можете использовать
keyAt
иvalueAt
некоторый индекс для циклического перемещения по коллекции, потому что онSparseArray
поддерживает отдельный индекс, отличный отint
ключей.Обратите внимание, что ключи упорядочены по возрастанию, а не в том порядке, в котором они были добавлены.
источник
Это только предупреждение из этой документации об этом редком массиве:
Это
SparseArray
сделано для более эффективного использования памяти, чем при использовании обычного HashMap, то есть не допускает множественных пробелов в массиве, как в HashMap. Вам не о чем беспокоиться, вы можете использовать традиционную HashMap, если вы не хотите беспокоиться о распределении памяти для устройства.источник
SparseArray
что ключевым целым числом не может быть поле Auto, что является еще одной операцией и экономически выгодным. вместо Map он будет автоматически вставлять примитивное целое числоInteger
Разреженный массив в Java - это структура данных, которая сопоставляет ключи со значениями. Та же идея, что и у карты, но другая реализация:
Карта представлена в виде массива списков, где каждый элемент в этих списках является парой ключ-значение. И ключ, и значение являются экземплярами объекта.
Разреженный массив состоит просто из двух массивов: массивов ключей (примитивов) и массива значений (объектов). В этих индексах массивов могут быть пробелы, отсюда и термин «разреженный» массив.
Основной интерес SparseArray заключается в том, что он экономит память, используя примитивы вместо объектов в качестве ключа.
источник
После некоторого поиска в Google я пытаюсь добавить информацию к уже опубликованным ответам:
Айзек Тейлор провел сравнение производительности для SparseArrays и Hashmaps. Он утверждает, что
и
Сравнение Edgblog показывает, что SparseArray требуется гораздо меньше памяти, чем HashMap, из-за меньшего ключа (int против Integer) и того факта, что
В заключение я бы сказал, что разница может иметь значение, если вы собираетесь хранить много данных на своей карте. В противном случае просто проигнорируйте предупреждение.
источник
Да, правильно. Но когда у вас есть только 10 или 20 предметов, разница в производительности должна быть незначительной.
Я думаю, что чаще всего мы используем только
HashMap
для поиска значения, связанного с ключом, в то время какSparseArray
это действительно хорошо.Исходный код SparseArray довольно прост и понятен, так что вам не нужно тратить много времени на его перенос на другие платформы (с помощью простого COPY & Paste).
Все, что я могу сказать, - (большинству разработчиков) кого это волнует?
Другим важным аспектом
SparseArray
является то , что он использует только массив для хранения всех элементов , в то время какHashMap
использованиеEntry
, такSparseArray
стоит значительно меньше памяти , чемHashMap
см этоисточник
К сожалению, компилятор выдает предупреждение. Я предполагаю, что HashMap слишком часто использовался для хранения предметов.
SparseArrays имеют свое место. Учитывая, что они используют алгоритм двоичного поиска, чтобы найти значение в массиве, вы должны учитывать, что вы делаете. Двоичный поиск - O (log n), а поиск по хешу - O (1). Это не обязательно означает, что бинарный поиск медленнее для данного набора данных. Тем не менее, по мере увеличения количества записей, власть хеш-таблицы вступает во владение. Отсюда комментарии, где небольшое количество записей может быть равным и, возможно, лучше, чем использование HashMap.
Хэш-карта хороша только как хеш-код, и на нее также может влиять коэффициент загрузки (я думаю, что в более поздних версиях они игнорируют коэффициент загрузки, поэтому его можно лучше оптимизировать). Они также добавили вторичный хеш, чтобы убедиться, что он хорош. Также причина, по которой SparseArray работает очень хорошо для относительно небольшого количества записей (<100).
Я бы посоветовал вам, если вам нужна хеш-таблица и вы хотите лучше использовать память для примитивного целого числа (без автобокса) и т. Д., Попробуйте trove. ( http://trove.starlight-systems.com - лицензия LGPL). (Нет связи с trove, как и их библиотека)
Благодаря упрощенному мульти-декс-билдингу у вас нет необходимости переупаковывать набор для того, что вам нужно. (У Троу много классов)
источник