Как hashCode () и identityHashCode () работают в серверной части?

Как Object.hashCode() и _2 _ работать в бэк-энде? identityHashCode() возвращает ссылку на объект? hashCode() зависит от содержания или адреса объекта?

В чем разница между hashCode() и identityHashCode()?


person Himanshu    schedule 08.02.2011    source источник
comment
Как JVM гарантирует, что System.identityHashCode ( ) никогда не изменится? поможет прояснить некоторую двусмысленность.   -  person Abhijeet    schedule 11.07.2016


Ответы (5)


Как Object.hashCode () и System.identityHashCode () работают в серверной части?

Предполагая, что он не был переопределен, метод Object.hashCode() просто вызывает System.identityHashCode(this).

Точное поведение System.identityHashCode(Object) зависит от реализации JVM. (Фактическая реализация на последних JVM Hotspot довольно умна, но я отвлекся.)

identityHashCode() возвращает ссылку на объект?

Нет. Он возвращает int, а int не может содержать ссылку.

Это целое число, возвращаемое identityHashCode, может быть связано с (а) машинным адресом объекта или не может быть 1. Значение, возвращаемое identityHashCode() , гарантированно не изменится в течение всего времени существования объекта. Это означает, что если GC перемещает объект (после вызова identityHashCode()), он не может использовать новый адрес объекта в качестве хэш-кода идентификации.

Зависит ли hashCode () от ? оператора ? == объекта, как работать в бэкэнде.

В этом нет смысла. В Java нет операторов ? == или ?==.

В чем разница между hashCode () и identityHashCode ()?

Частично это объяснено выше. Другие отличия включают:

  • Метод hashcode() не является конечным методом экземпляра и должен быть переопределен в любом классе, где переопределяется equals(Object). Напротив, identityHashCode(Object) является static методом и поэтому не может быть отменен.

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


1 - Для JVM текущего поколения это вообще не связано с адресом памяти. См. Ответ @ bestsss.

person Stephen C    schedule 08.02.2011

identityHashCode() работает так (и на данный момент он не имеет ничего общего с адресом, особенно, поскольку адреса имеют длину 64 бита, выровнены нормально, поэтому 61 ​​):

Проверяет, есть ли уже сгенерированный, если да, возвращает. Вы можете предположить, что в заголовке объекта есть место для этого int;

В противном случае: генерирует случайное число (алгоритм Marsaglia shift-xor). Каждый собственный поток имеет собственное семя, поэтому общей информации нет. CAS поле identityHashCode в заголовке объекта для обновления вновь сгенерированного числа. В случае успеха CAS возвращает значение. В противном случае поле уже содержит сгенерированный identityHashCode.

Вы можете увидеть остальные ответы о переопределении хэш-кода.

Итог: если в JavaDoc по-прежнему что-то говорится об адресах и identityHashCode, кто-то должен его обновить.

person bestsss    schedule 08.02.2011
comment
В коде есть 5 вариантов расчета хеш-кода. Глядя на здесь видно, что в настоящее время действительно используется вариант 5, Marsaglia shift-xor. Генерация хэш-кода подробно описана в этом сообщение в блоге - person eis; 28.08.2017

Это в значительной степени зависит от реализации. Единственная гарантия, которую вы получаете, это

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

(Из Java 1.6 JavaDoc)

Теоретически это означает, что значения могут быть определены произвольно и даже равны нулю для каждого объекта. На практике это, вероятно, что-то производное от адреса объекта. Конечно, с этим нужно быть осторожным. JVM может перемещать объекты, если считает это хорошей идеей во время сборки мусора, поэтому это не будет «просто» адресом памяти. Он может быть получен из глобального счетчика или хэша исходного местоположения объекта, или из генератора случайных чисел и т. Д.

person templatetypedef    schedule 08.02.2011
comment
Ты прав, я, должно быть, что-то перепутала. Я застрял в документации, чтобы подтвердить свой гипотез, но потерпел неудачу. ;-) удалил свой ответ и проголосовал за ваш! - person Björn; 08.02.2011
comment
в чем разница между hashCode () и identityHashCode ()? - person Himanshu; 08.02.2011
comment
@ Himanshu- Object.hashCode() является реализацией hashCode() по умолчанию и часто переопределяется производными классами, чтобы соответствовать правилам для _3 _ / _ 4_. System.identityHashCode() предоставляет способ получить значение, которое Object.hashCode() вернет для этого объекта, даже если он содержит переопределение для этого метода. Это позволяет создавать контейнеры, работающие с семантикой идентичности, поскольку == и System.identityHashCode() обрабатывают каждый объект уникально. - person templatetypedef; 08.02.2011
comment
Идея о том, что hashCode использует адрес памяти, является историческим артефактом stackoverflow.com/questions/36236615/ - person Raedwald; 26.03.2016

identityHashCode

общедоступный статический int identityHashCode (объект x)

Возвращает тот же хэш-код для данного объекта, который был бы возвращен методом по умолчанию hashCode (), независимо от того, переопределяет ли класс данного объекта hashCode (). Хэш-код для нулевой ссылки равен нулю.

См. [Java документы]

Поэтому, если кто-то переопределил метод hashCode() в своем классе, но по-прежнему хочет значение по умолчанию hashCode(), которое было бы возвращено Object hashCode(), используйте System.identityHashCode()

Итак, hashCode() внутренне вызывает System.identityHashCode() до тех пор, пока вы не переопределяете его в своем классе, если вы переопределите hashCode (), он вызовет вашу реализацию.

person Vishrant    schedule 30.03.2017

Выше дано много ответов, просто нужно добавить несколько баллов.

Когда мы говорим obj.hashCode(), содержимое объекта obj учитывается, с другой стороны, в System.identityHashCode(obj) содержимое не принимается во внимание, таким образом, identityHashCode для двух разных String, int (с одинаковым значением) будут разными, но Hashcode будет одинаковым.

В случае String для получения identityHashCode пул строк играет важную роль, например

    Object s1 = "abcd";
    Object s2 = new String("abcd");
    Object s3 = "abcd";
    System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());

    //output:
    identityHashCode : 2018699554 HashCode : 2987074
    identityHashCode : 1311053135 HashCode : 2987074
    identityHashCode : 2018699554 HashCode : 2987074

здесь s1 и s3 указывают на одну и ту же ссылку, поэтому identityHashCode для s1 and s3 всегда одно и то же, а s2 будет другим.

То же самое и для int, IntegerCache играет важную роль для получения identityHashCode

    Object s1 = 5;
    Object s2 = new Integer(5);
    Object s3 = 5;
    System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
    System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());

    //Output
    identityHashCode : 2018699554 HashCode : 5
    identityHashCode : 1311053135 HashCode : 5
    identityHashCode : 2018699554 HashCode : 5
person Hitesh Ghuge    schedule 15.09.2018