Лучший способ инициализировать HashMap - PullRequest
3 голосов
/ 25 сентября 2011

Обычно я делаю, например,

HashMap<String,String> dictionary = new HashMap<String,String>();

Я начал думать об этом, и, насколько я знаю, HashMap реализован под капотом через хеш-таблицу.
Объекты хранятсяв таблице, используя хэш, чтобы найти, где они должны храниться в таблице.

Означает ли тот факт, что я не устанавливаю размер для конструкции dictionary, снижение производительности?
Т.е. каков будет размер хеш-таблицы во время построения?Нужно ли выделять новую память для таблицы при увеличении элементов?
Или я не совсем понимаю концепцию, приведенную здесь?
Достаточны ли емкость и нагрузка по умолчанию или я должен тратить время на фактические числа?

Ответы [ 5 ]

5 голосов
/ 25 сентября 2011

Означает ли тот факт, что я не устанавливаю размер для конструкции словаря, снижение производительности?

Зависит от того, сколько вы собираетесь хранить в HashMap и как ваш код будет использовать его позже.Если вы можете дать ему примерный показатель заранее, это может быть быстрее, но: «очень важно не устанавливать слишком высокую начальную емкость [...], если важна производительность итерации» * 1 , потому что итерациявремя пропорционально емкости.

Выполнение этого в не критичных для производительности фрагментах кода будет считаться преждевременной оптимизацией.Если вы собираетесь перехитрить авторов JDK, убедитесь, что у вас есть измерения, которые показывают, что ваша оптимизация имеет значение.

каков будет размер хеш-таблицы во время построения?

В соответствии с API документами , 16.

Нужно ли выделять новую память для таблицы при увеличении элементов?

Да,Каждый раз, когда он полнее, чем коэффициент загрузки (по умолчанию = 0,75), он перераспределяет.

Являются ли емкость по умолчанию и адекватная нагрузка

Только вы можете сказать.Профилируйте свою программу, чтобы увидеть, тратит ли она слишком много времени на HashMap.put.Если это не так, не беспокойтесь.

4 голосов
/ 25 сентября 2011

Приятной особенностью Java является то, что она имеет открытый исходный код, поэтому вы можете получить исходный код , который отвечает на ряд вопросов:

  1. Нет, между HashMap и HashTable нет никакой связи. HashMap происходит от AbstractMap и не использует внутренне HashTable для управления данными.

  2. Уменьшит ли производительность явный размер или нет, будет зависеть от вашей модели использования (или, точнее, от того, сколько вещей вы положили на карту). Размер карты автоматически удваивается при каждом достижении определенного порога (0,75 * <current map capacity>), а операция удвоения стоит дорого. Так что, если вы приблизительно знаете, сколько элементов будет добавлено на карту, вы можете указать размер и предотвратить необходимость в выделении дополнительного пространства.

  3. Емкость карты по умолчанию, если она не указана с помощью конструктора, равна 16. Таким образом, она удвоит емкость до 32, когда 12-й элемент будет добавлен на карту. А потом снова 24-го и т. Д.

  4. Да, ему нужно выделять новую память при увеличении емкости. И это довольно дорогая операция (см. Функции resize() и transfer()).

Не имеет отношения к вашему вопросу, но все же стоит отметить, я бы порекомендовал объявить / создать экземпляр вашей карты, например:

Map<String,String> dictionary = new HashMap<String,String>();

... и, конечно, если вы знаете, сколько элементов будет размещено на карте, вы должны указать и это.

1 голос
/ 25 сентября 2011

Прежде всего, я бы объявил его интерфейсной картой.

Map<String,String> dictionary = new HashMap<String,String>();

Уменьшает ли производительность тот факт, что я не устанавливаю размер в конструкции словаря?

Да, для повышения производительности следует установить начальную емкость.

Нужно ли выделять новую память для таблицы при увеличении элементов

Да,коэффициент загрузки также влияет на производительность.

Подробнее в документах

1 голос
/ 25 сентября 2011

Hashmap будет автоматически увеличивать размер, если это необходимо.Лучший способ инициализации - это если у вас есть какой-то прогноз, сколько элементов вам может понадобиться, и если эта цифра велика, просто установите ее в число, которое не требует постоянного изменения размера.Более того, если вы прочитаете JavaDoc для Hashmap , вы увидите, что размер по умолчанию равен 16, а коэффициент загрузки равен 0,75, что означает, что, как только хэш-карта заполнится на 75%, она автоматически изменит свой размер.Поэтому, если вы планируете хранить 1 миллион элементов, естественно, вам нужен больший размер, чем по умолчанию

0 голосов
/ 25 сентября 2011

Как указано здесь , начальная емкость по умолчанию равна 16, а коэффициент загрузки по умолчанию равен 0,75.Вы можете изменить любой из них с разными цветами, и это зависит от вашего использования (хотя, как правило, это хорошо для общих целей).

...