ИМХО, причина для реализации как хеш-кода, так и равных заключается в следующем:
Хеш-таблица обеспечивает быстрый доступ к элементам на основе ключей. Это возможно благодаря его реализации.
Хеш-таблица внутренне использует сегменты для хранения своих значений. Думайте о каждом ведре как о массиве.
И есть множество таких ведер. Поэтому он становится двумерным массивом. Хеш-код ключа - это механизм, с помощью которого хеш-таблица может напрямую переходить к индексу корзины, в которой хранится значение.
Например:
Ниже я написал код для класса, который я буду использовать в качестве ключа для экземпляра HashMap.
package com.aneesh.hashtable;
import java.util.HashMap;
public class Key {
private String key;
public Key(String key){
this.key = key;
}
@Override
public int hashCode() {
return key.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Key other = (Key) obj;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
return true;
}
public static void main(String[] args) {
HashMap<Key, String> hashMap = new HashMap<Key, String>();
hashMap.put(new Key("a"), "java");
hashMap.put(new Key("k"), "Python");
System.out.println(hashMap.get(new Key("a")));
System.out.println(hashMap.get(new Key("k")));
}
}
Реализация hashCode класса Key должна просто возвращать hashCode переменной экземпляра 'key', имеющей тип String.
Хеш-код для "а" = 97
Хеш-код для "k" = 107 // есть причина, по которой я выбираю эти два ключа, которая скоро станет очевидной.
Когда вы делаете hashMap.put (новый ключ ("a"), "java");
Хеш-таблица должна выяснить, в какую корзину она должна поместить ключ, значение. Код для этого будет
int indexofBucket = key.hashCode() % numberOfBuckets //7, where key is "a"
Таким образом, пара ключ-значение ("a," java ") будет сохранена как первый элемент в 7-м сегменте.
Когда вы делаете hashMap.put (новый ключ ("k"), "python");
индекс ведра снова рассчитывается как
indexofBucket = key.hashCode ()% numberOfBuckets // 7, где key = "k"
Это то же самое ведро, ведро на седьмом указателе.
Теперь, когда вы получаете значение по его ключу
hashMap.get(new Key("a"));
хеш-таблица вычислит индекс таким образом:
indexOfBucket = key.hashCode() % numberOfBuckets //7
В этот момент хеш-таблица найдет два элемента в корзине. Теперь, какой элемент является тем, который он должен возвращать, будет решено (в простой реализации, я думаю) итерацией по каждому элементу и сравнением равных ключей. Без равных хеш-таблица может даже не найти элемент, который вы добавили в него.
Чтобы увидеть это в действии, закомментируйте реализацию класса равных Key и запустите код. Вы увидите
null
null
выводится как вывод, тогда как при внедрении равных вы увидите вывод
"java",
"python"
Длинное раненое объяснение, но надеюсь, что это поможет