Comments 22
Мне в свое время зашли такие статьи
https://habr.com/ru/articles/128017/
У автора ещё немного есть
а бывает HashMap с транзакциями. но на Жабе у вас не получится.
Шо, опять?!?
Удивительно, что вы не написали стандартную в таких случаях фразу, - я не нашёл на хабре ничего про устройство хэшмапы... Просто интересно, что могло побудить вас написать ещё одну однотипную статью к доброму десятку уже имеющихся?
А когда это получение значения из hashmap имеет сложность o(n)?
Или что значит фраза " Вставка и получение элементов имеют имеют сложность O(1) или О(n), или O(logN)"?
Если у добавленных значений совпадает хэш, они попадут в один бакет в формате связного списка. Работа со списком как раз и даёт O(N). Но, при достижении определенного размера, список будет преобразован в дерево, где сложность уже O(logN), в целях оптимизации.
Такая ситуация возможна, если функция хэширования реализована плохо и, как следствие, имеет много коллизий
Это не совсем верное утверждение. Список в бакете не превышает 8 элементов, так что O(N) получить никак не получится.
Все так, если количество элементов в бакете превышает TREEIFY_THRESHOLD (который как раз и равен 8), то будет вызван метод treeifyBin и бакет преобразуется в красно-черное дерево.
Благодаря этому, начиная с Java 8+
производительность java.util.HashMap
в худшем случае не O(n)
, а O(log n)
.
В случае отсутствия ключа в мапе возвращается null, поэтому стоит предварительно проверять наличие пары через
containsKey(Object key)
, иначе можем получитьNullPointerException
в дальнейшем.
Вредительский совет. Зачем для получения значения 2 раза осуществлять его поиск? Просто результат получения значения на null проверять и всё
Более того. В многопотоке (если кто-то накосячил), то можно от if xxx.containsKey() получить истину, а далее получить null при вычитывании сущности.
Согласен. Лишнего вызова стоит избегать всегда по дефолту.
В целом проблему с null можно решить так:
- не ложить null
- ложить "специальное" пустое значение
- проверять через .containsXXX()
- перестроить логику, что бы было не важно "нет или null"
Хорошо. + я бы добавил сюда еще инфу по памяти потребляемой. Ведь это всегда конфликт - память/скорость.
Грубо говоря например, тюнингом я могу больше приблизить скорость к О(1), если буду увеличивать число бакетов (уменьшая лоад фактор и число потенциальных коллизий для "нехорошего" хеша). Но тогда взлетит память. И в том "на сколько", и будет заключаться дилемма, которую нужно будет решать оптимизатору.
Поэтому я бы не разделял скорость и память.
Вы не упомянули важную вещь, а именно - это то, как список будет преобразовываться в дерево (и в какое дерево именно), а также вклад в таком случае Comparable.
Вот тут я разбирал как это будет происходить: JBook/HashMap#коллизии
Ну и вообще, сама заметка про HashMap, может будет кому полезно: JBook
Подскажите как|чем в таком интересном виде "доки" в коде выводить?

HashMap под микроскопом