2016-08-28 6 views
-2

В каждой статье о столкновении хэшей HashMaps есть одна вещь, и мой вопрос вращается вокруг этого.Какой метод .equals() вызывается для разрешения столкновения хэша в HashMaps?

Позвольте мне объяснить, что я понимаю о внутренней работе hashmaps.

Сохранение двух записей (E1, E2) с использованием той же хэш-код map.put (K, V)

1), когда map.put (K, V) называется, HashMap находит хэш-код () ключа 'k'.

2) тогда он использует этот хэш-код, который он нашел в качестве семени для своего внутреннего статического метода хэширования. & получает другое значение хэш-функции.

3) тогда это новое найденное значение хэширования отображается на внутренний индекс ведра.

4) затем в корзину добавляется запись.

В случае столкновения хэшей.

1) то же самое, что и нормальный, когда вызывается map.put (k, v), hashmap находит hashCode() ключа 'k'.

2) снова такой же, как обычно, тогда он использует этот хэш-код, который он нашел в качестве семени для своего внутреннего статического метода хэширования. & получает другое значение хэш-функции.

3) новое найденное хеш-значение отображается на внутренний индекс ведра, теперь есть проблема, так как он уже имеет запись в этом положении ковша.

Разрешение: Поскольку запись на самом деле является простым связанным списком, новый элемент с конфлицированным хешем сохраняется в следующей предыдущей записи.

Извлечение входа e2 с map.get (к)

1) хэш генерируется из ключа & снова статический метод вызывается с использованием хэш-хэш получить из ключа в качестве затравки.

2) обнаружение сопоставленного ведра с использованием значения хеширования, полученного статическим хеш-методом, теперь, если здесь имеется более одной записи метод equals() приходит на помощь.

, который связан с перечнем &, продолжает называть метод equals(), пока не найдет совпадение.

Теперь мой вопрос в том, где это так называется метод equals()?

Я открыл официальную документацию HashMap &, но не переопределяет метод .equals(), , так где это происходит? Или это значение по умолчанию .equals() из класса Object?

+2

Ждать, что? 'HashMap' не вызывает собственный метод equals, это не имеет смысла, он называет объекты равными методу, который вы пытаетесь вставить. – tkausl

+0

@tkausl вы можете объяснить это более подробно? Вы хотите сказать, что значение по умолчанию «==» в классе Object равно() используется для поиска ключа? –

ответ

3

Оба метода hashCode() и equals() относятся к классу ключевого объекта, а не к хэш-карте.

Методы определены в классе Object, но предполагается, что объекты, используемые в качестве ключей в хэш-карте, обеспечивают их собственную реализацию для обоих этих методов. Таким образом, это не по умолчанию.equals() от Object класс, это .equals() от фактического класса ключа, который вызывается для разрешения конфликтов.

Например, если вы используете String объектов в качестве ключей, переопределение из hashCode() и equals() предоставленного String будет использоваться.

+0

поэтому по умолчанию, если я не указываю equals() в ключе, будут использоваться ссылки класса Key? Это подводит меня к другому вопросу, что, если я добавлю два ключевых объекта с одинаковым значением, но с разными ссылками? EX - Строка key1 = "игра тронов"; Строка key2 = новая строка («игра престолов»); Как это повлияет на поиск? –

+0

@SujalMandal Ситуация, которую вы описываете, демонстрирует именно причину, по которой 'equals' используется вместо' == '. У вас есть две разные ссылки на объекты, которые имеют значения, равные друг другу, поэтому '==' возвращает 'false', но' key1.equals (key2) 'возвращает' true'. – dasblinkenlight

+2

@SujalMandal По умолчанию 'equals()' унаследованный от объекта возвращает true только при сравнении двух одинаковых экземпляров, независимо от значений. 'String', однако реализует' equals() ', поэтому ваши две строковые ключи будут считаться равными и, следовательно, одним и тем же ключом. Обычно рекомендуется, чтобы все объекты перезаписывали 'equals()' и 'hashcode()' особенно, если вы собираетесь использовать их как ключи на карте. – puhlen