Другими словами, является ли целое число, возвращаемое hashCode(), уже индексом записи в хеш-таблице, или ему нужно сделать еще один шаг, сжав себя до индекса (возможно, изменяя длину таблицы)?
Учитывая, что вы можете поместить один и тот же объект в две (или более) хеш-таблицы разного размера (или нулевые хеш-таблицы), индекс какой таблицы, по вашему мнению, вернет метод hashCode?




Нет, хэш-коды вычисляются независимо от целевой хеш-таблицы. Хэш-код целого числа, например, является самим целым числом, поэтому хеш-таблице, как правило, потребуется снова выполнить хеш-код мода, чтобы поместить его в таблицу.
Тогда кажется, что метод hashCode не может гарантировать отсутствие коллизий, потому что два хэш-кода из двух разных объектов могут быть сжаты в один и тот же индекс таблицы (например, hashcode1 = 7, hashcode2 = 14, tableLength = 7, поэтому idx1 = idx2 = 0). Если да, то в чем смысл хэш-кодов?
Чтобы сделать коллизии невероятно, или хотя бы как можно более маловероятными. Каждая реализация хеш-таблицы должна иметь дело с коллизиями, вы просто пытаетесь их уменьшить.
@OneFlowerOneWorld более того, вы, кажется, думаете, что хэш-коды уникальны. Это не так. Многие объекты имеют одинаковый хэш-код.
@OneFlowerOneWorld существует 2 ^ 64 различных значения Long, но только 2 ^ 32 возможных хэш-кода. Просто должно быть столкновение.
@JBNizet Думаю, я запутался больше. Тогда для чего нужен hashCode() и как сделать так, чтобы объекты моего собственного класса можно было использовать в качестве ключей HashMap?
Вы реализуете hashCode () и equals (), как описано в документации, и делаете свой класс неизменяемым. Опять же, hashCode используется для уменьшения количества элементов для сравнения при поиске. Представьте, что у вас есть 500 ключей, хранящихся в 100 разных корзинах (что является довольно плохим распределением хешей). Получается 5 ключей на ведро. Итак, чтобы узнать, существует ли ключ K в хэш-таблице, вам нужно только сравнить его с 5 другими ключами (5 ключей в корзине, выбранной хэш-кодом K). Это в 100 раз эффективнее, чем сравнение с 500 другими ключами.
При приличном распределении хешей у вас обычно есть 0 или 1 ключ на ведро, что делает поиск очень быстрым. Возвращаясь к уникальности хэш-кодов: это простая логическая проблема: существует только 2 ^ 32 возможных хэш-кода. Взять хотя бы лонги: их 2 ^ 64. Очевидно, что многие из них имеют один и тот же хэш-код. Но вы обычно храните только несколько экземпляров Long на карте, и поэтому вероятность столкновения намного меньше.
@JBNizet Таким образом, разные хэш-коды не обязательно приводят к разным корзинам, но одни и те же хэш-коды связаны с доступом к одной и той же корзине, и поэтому мы должны сделать хэш-коды для разных объектов (отличающихся методом equals) разными, чтобы уменьшить вероятность коллизий (хотя нет -коллизия не гарантируется)? А экземпляр Integer со значением 65536 не обязательно находится в 65536-м ведре (это зависит от длины таблицы)?
Нет. Хеш-таблицы почти всегда имеют гораздо меньше сегментов, чем 2 ^ 32. Исходный код JDK поставляется вместе с JDK. Почему вы не читаете исходный код (или даже просто документацию)?