Как работает метод hashCode () Java? - PullRequest
16 голосов
/ 25 декабря 2009

Мне любопытно, как java генерирует хеш-значения, используя hashCode () метод Object API?

Ответы [ 6 ]

24 голосов
/ 25 декабря 2009

hashCode() из Object на самом деле является нативным методом, а реализация на самом деле не является чистой Java. Теперь, что касается того, как это работает, этот ответ Тома Хоутина отлично объясняет это:

Многие люди утверждают, что Object.hashCode вернет адрес представления объекта в памяти. В современных реализациях объекты фактически перемещаются в памяти. Вместо этого для хранения значения используется область заголовка объекта, которая может быть лениво извлечена из адреса памяти в момент первого запроса значения.

Весь ответ действительно стоит прочитать.

10 голосов
/ 25 декабря 2009

Java не генерирует hashCode (), то есть здесь ничего не происходит автоматически. Однако Object генерирует HashCode на основе адреса памяти экземпляра объекта. Большинство классов (особенно если вы собираетесь использовать его в любом из Collection API) должны реализовывать свой собственный HashCode (и, по контракту, свой собственный метод equals).

5 голосов
/ 25 декабря 2009

Согласно документации API Java Platform, расчет хеш-кода основан на 32-битном внутреннем адресе JVM объекта.

Это правда, что объект перемещается во время выполнения (AFAIK единственная причина - сборщик мусора). Но хеш-код не меняется.

Итак, когда у вас есть такой объект

Person person1 = new Person();
person1.setName("Alex");

Person person2 = new Person();
person2.setName("Alex");

Person person3 = person2;

В этом случае person1.hashCode не будет равен person2.hashCode, поскольку адреса памяти этих двух объектов не совпадают.

Но person2.hashCode будет равен person3, потому что они указывают на один и тот же объект.

Так что, если вам нужно использовать метод hashCode для ваших объектов, вы должны реализовать его самостоятельно.

Кстати, Реализация String.hashCode отличается . Это что-то вроде этого: (C # синтаксис)

public int hashCode(String str)
{
  int h = 0;

  for (int i = 0; i < str.Length; i++)
    h = (h * 31) + str[i];

  return h;
}

edit: Здесь не выполняется проверка переполнения, поэтому hashCode может быть положительным или отрицательным.

4 голосов
/ 25 декабря 2009

Object.hashCode () использует System.identityHashCode (), который основан на номере идентификатора для данного объекта.

2 голосов
/ 07 марта 2017

Функция HashCode () имеет несколько опций для создания хеш-кода. Устанавливает параметр запуска JVM. Функция, которая создает hashCode () написана на C ++, и вы можете увидеть код здесь

  • HashCode == 0: Просто возвращает случайные числа без отношения к где в памяти объект найден. Насколько я могу понять, глобальный чтение-запись семени не является оптимальным для систем с большим количеством процессоры.
  • HashCode == 1: Подсчитывает значения хеш-кода, не уверен, какое значение они начинаются, но это кажется довольно высоким.
  • HashCode == 2: Всегда возвращает один и тот же хэш-код идентичности 1. Это может быть использовано для тестирования кода, основанного на идентичности объекта. причина, по которой JavaChampionTest возвратил URL Кирка в приведенном выше примере является то, что все объекты возвращали один и тот же хэш-код.
  • HashCode == 3: Подсчитывает значения хеш-кода, начиная с нуля. Это не выглядит потокобезопасным, поэтому несколько потоков может генерировать объекты с одинаковым хеш-кодом.
  • HashCode == 4: Кажется, это имеет отношение к месту в памяти в котором объект был создан.
  • HashCode> = 5: Это алгоритм по умолчанию для Java 8 и имеет на семя нити. Он использует схему XOR-сдвига Marsaglia для производства псевдослучайные числа.

Информация взята с здесь

1 голос
/ 25 декабря 2009

Java не дает значимого hashCode для вас, ваша работа как программиста - генерировать полезные hashCode. По умолчанию hashCode - это просто область памяти.

...