HashMap

Базовый Java
≈ 2 мин чтения

Как HashMap находит значение

HashMap<K, V> — одна из самых часто используемых реализаций Map. Её основная идея — превратить ключ в хеш и с его помощью быстро найти область, где должна находиться нужная запись.

Map<String, String> capitals = new HashMap<>();
capitals.put("France", "Paris");
capitals.put("Japan", "Tokyo");

System.out.println(capitals.get("Japan"));

В среднем основные операции put(), get() и remove() выполняются за время, близкое к постоянному. Это и делает HashMap хорошим выбором, когда главная задача — быстро работать по ключу.

hashCode и equals работают вместе

При поиске ключа карта использует hashCode(), чтобы сузить место поиска, а затем equals(), чтобы отличить нужный ключ от других. Ты уже знаешь контракт этих методов; здесь становится видно, зачем он нужен на практике.

Два разных ключа могут получить одинаковый хеш. Это называется коллизией и само по себе не является ошибкой: HashMap умеет хранить несколько таких записей и различать их через equals(). Проблемы начинаются, если сами методы равенства реализованы несогласованно.

Ключ не должен «переезжать» после добавления

Опасно менять те поля ключа, от которых зависят equals() и hashCode(), пока ключ находится в карте. После изменения карта может искать объект уже по другому хешу и не найти запись там, куда она была помещена изначально.

Лучшие ключи — стабильные. Строки, числа, enum и другие неизменяемые значения удобны именно потому, что их равенство и хеш не меняются неожиданно во время хранения в HashMap.

Порядок не гарантируется

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