Как вычисляется hashcode java
Hashcode в Java вычисляется с помощью метода hashCode()
.
Он возвращает целочисленное значение, используемое для идентификации объекта. Для вычисления Java использует алгоритм хеширования, который преобразует данные объекта в целочисленное значение. Реализация алгоритма зависит от JVM.
public class App {
public static void main(String[] args) {
Object myObject = new Object();
System.out.println(myObject.hashCode()); // => 1995265320
String myStr = "Hello";
System.out.println(myStr.hashCode()); // => 69609650
Integer myInt = 5;
System.out.println(myInt.hashCode()); // => 5
}
}
Мы можем переопределить метод hashСode()
для своих объектов. При этом необходимо учитывать следующее :
1) Согласно контракту методы hashCode()
и equals()
переопределяются одновременно.
2) Правила переопределения :
- вызов метода
hashCode()
один и более раз над одним и тем же объектом должен возвращать одно и то же хэш-значение, при условии что поля объекта, участвующие в вычислении значения, не изменялись. - вызов метода
hashCode()
над двумя объектами должен всегда возвращать одно и то же число, если эти объекты равны (вызов методаequals()
для этих объектов возвращает true). - вызов метода
hashCode()
над двумя неравными между собой объектами должен возвращать разные хэш-значения. Хотя это требование и не является обязательным, следует учитывать, что его выполнение положительно повлияет на производительность работы хэш-таблиц.
3) Кроме того хороший хэшкод должен
- быстро вычисляться
- равномерно распределять значения для объектов класса
После переопределения первоначальный (идентификационный) хеш доступен через метод System.identityHashCode()
.
Подход к вычислению hashcode в Java может быть различным, но основной механизм определён в классе Object
, который является родителем для всех классов в Java. Метод hashCode()
предназначен для получения хэш-кода объекта, и важен для работы хэш-таблиц, например, в таких структурах данных, как HashMap
, HashSet
, и Hashtable
.
Переопределение hashCode()
При переопределении hashCode()
, рекомендуется следовать контракту hashCode, который включает в себя три основных правила:
Постоянство хэш-кода: При многократных вызовах метода
hashCode()
во время выполнения одной и той же программы, метод должен возвращать одно и то же целое число, при условии, что в объекте не было изменений, влияющих на сравнениеequals(Object)
. Это значение не обязано оставаться постоянным от одного выполнения приложения к другому.Равенство объектов ведет к равенству хэш-кодов: Если два объекта равны согласно методу
equals(Object)
, то вызовhashCode()
для этих объектов должен возвращать одно и то же целое число.Неравные объекты могут иметь равные хэш-коды: Если два объекта не равны согласно методу
equals(Object)
, это не обязательно означает, что они должны возвращать разные хэш-коды. Однако создатели класса должны понимать, что разные хэш-коды могут улучшить производительность хэш-таблиц.
public class Person {
private String name;
private int age;
@Override
public int hashCode() {
int result = 17;
result = 31 * result + name.hashCode();
result = 31 * result + age;
return result;
}
}
В этом примере используется 31, простое число, что является общепринятой практикой для получения более равномерного распределения хэш-кодов. name.hashCode()
используется для получения хэш-кода строки, а age
является примитивным типом, поэтому он напрямую участвует в вычислении.