Редактировать : Я только что видел, что вы упомянули, что String были британскими почтовыми индексами, поэтому я вполне уверен, что вы не ошибетесь, используя Trove TLongIntHashMap (кстати, Trove - это небольшая библиотека и она очень проста в использовании).
Редактировать 2 : Многим людям этот ответ кажется интересным, поэтому я добавляю к нему некоторую информацию.
Целью здесь является использование карты, содержащей ключи / значения, с эффективным использованием памяти, поэтому мы начнем с поиска коллекций с эффективным использованием памяти.
Следующий вопрос SO связан (но далеко не идентичен этому).
Какая библиотека Java Collections наиболее эффективна?
Джон Скит упоминает, что Trove является "просто библиотекой коллекций из примитивных типов" [sic] и что, действительно, он не добавляет много функциональности. Мы также можем увидеть несколько тестов ( the.duckman ) о памяти и скорости Trove по сравнению с коллекциями по умолчанию. Вот фрагмент кода:
100000 put operations 100000 contains operations
java collections 1938 ms 203 ms
trove 234 ms 125 ms
pcj 516 ms 94 ms
А также есть пример, показывающий, сколько памяти можно сохранить, используя Trove вместо обычной Java HashMap :
java collections oscillates between 6644536 and 7168840 bytes
trove 1853296 bytes
pcj 1866112 bytes
Таким образом, несмотря на то, что эталонные тесты всегда нужно брать с небольшим количеством соли, совершенно очевидно, что Trove сохранит не только память, но всегда будет намного быстрее.
Таким образом, наша цель теперь заключается в использовании Trove (видно, что, помещая миллионы и миллионы записей в обычный HashMap , ваше приложение перестает отвечать на запросы).
Вы упомянули 2 миллиона пар, ключи длиной 7 символов и отображение String / int.
2 миллиона - это на самом деле не так много, но вы все равно будете ощущать издержки «Объекта» и постоянное (не) упаковывание примитивов в Integer в обычном HashMap {String, Integer}, поэтому Trove создает много смысла здесь.
Однако я хотел бы отметить, что если у вас есть контроль над «7 символами», вы можете пойти еще дальше: если вы используете, скажем, только символы ASCII или ISO-8859-1, ваши 7 символов будут соответствовать вместе (*). В этом случае вы можете полностью избежать создания объектов и представлять своих 7 персонажей на длинной. Затем вы бы использовали Trove TLongIntHashMap и вообще обошли бы «Java-объект».
Вы специально указали, что ваши ключи имеют длину 7 символов, а затем прокомментировали, что они являются британскими почтовыми индексами: я бы отображал каждый почтовый индекс на длинный и сохранял огромный объем памяти, помещая в память пару ключей / значений, используя Trove.
Преимущество Trove в основном в том, что не выполняет постоянную упаковку / распаковку объектов / примитивов: во многих случаях Trove работает напрямую только с примитивами и примитивами.
(*) говорят, что вы используете не более 256 кодовых точек / символов, тогда он умещается в 7 * 8 == 56 бит, что достаточно мало, чтобы соответствовать длинному.
Пример метода для кодирования ключей String
в long
(предполагается, что для упрощения используются символы ASCII, один байт на символ - достаточно 7 бит):
long encode(final String key) {
final int length = key.length();
if (length > 8) {
throw new IndexOutOfBoundsException(
"key is longer than 8 characters");
}
long result = 0;
for (int i = 0; i < length; i++) {
result += ((long) ((byte) key.charAt(i))) << i * 8;
}
return result;
}