Почему hashCode () возвращает одно и то же значение для объекта во всех последовательных выполнениях? - PullRequest
11 голосов
/ 06 июня 2010

Я пытаюсь код вокруг равенства объектов в Java. Как я где-то прочитал

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

Теперь у меня есть пример программы, которую я запускаю 10 раз подряд. Каждый раз, когда я запускаю программу, я получаю то же значение, что и хэш-код.

Если функция hashCode() возвращает ячейку памяти для объекта, почему java (JVM) сохраняет объект с тем же адресом памяти в последовательных прогонах?

Не могли бы вы дать мне некоторое представление и ваше мнение по этому вопросу?

Программа, которую я запускаю для проверки этого поведения, приведена ниже:

public class EqualityIndex {

    private int index;

    public EqualityIndex(int initialIndex) {
       this.index = initialIndex;
    }

    public static void main(String[] args) {
        EqualityIndex ei = new EqualityIndex(2);
        System.out.println(ei.hashCode());
    }

}

Каждый раз, когда я запускаю эту программу, возвращается значение хеш-кода 4072869.

Ответы [ 8 ]

15 голосов
/ 06 июня 2010

почему java (JVM) хранит объект по одному и тому же адресу памяти в последовательных прогонах?

Почему бы и нет? Неядерные программы никогда не работают с абсолютными адресами памяти, они используют виртуальную память, где каждый процесс получает свое собственное адресное пространство. Поэтому нет ничего удивительного в том, что детерминированная программа будет размещать вещи в одном и том же месте при каждом запуске.

4 голосов
/ 06 июня 2010

Ну, объекты вполне могут оказаться в одном месте в виртуальной памяти. Ничего противоречивого в этом нет. Суть в том, что вам все равно. Если , то хэш-код реализован так, чтобы возвращать что-то, связанное с адресом внутренней памяти (гарантия вообще отсутствует!), В любом случае вы ничего не можете сделать с этой информацией.

3 голосов
/ 06 июня 2010

Функция hashCode() должна возвращать одно и то же значение для того же объекта в том же исполнении. Нет необходимости возвращать одно и то же значение для другого выполнения. Смотрите следующие комментарии, которые были извлечены из класса Object.

Общий контракт hashCode:

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

Я выполнил ваш код несколько раз. Вот мой результат

1935465023

1425840452

1935465023

1935465023

1935465023

1925529038

1935465023

1935465023

Один и тот же номер повторяется несколько раз. Но это не значит, что они всегда одинаковы. Предположим, что конкретная реализация JVM ищет первый свободный слот в памяти. затем, если вы не запускаете никаких других приложений, высока вероятность размещения объекта в том же слоте.

2 голосов
/ 06 июня 2010

Как я где-то читал: "... На уровне объекта он возвращает адрес памяти объекта."

Это утверждение неверно или, в лучшем случае, упрощено.

Оператор ссылается на реализацию по умолчанию Object.hashCode(), которая возвращает то же значение, что и System.identityHashcode(Object).

Javadoc для Object.hashCode() говорит это:

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

и это:

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

Фактически значение хэш-кода идентификатора обычно основывается на машинном адресе Объекта , когда метод впервые вызывается для объекта . Значение хранится в скрытом поле в заголовке объекта. Это позволяет возвращать тот же хеш-код при последующих вызовах ... даже если GC тем временем переместил объект.

Обратите внимание, что если значение хеш-кода идентификатора изменилось за время существования объекта, это нарушило бы контракт для hashcode() и было бы бесполезным в качестве хеш-кода.

2 голосов
/ 06 июня 2010

Какие объекты вы создали? Это особый вид объекта, например String (например,). Если это определенный тип, класс уже может переопределить метод hashCode () и вернуть его вам. В этом случае то, что вы получаете, больше не является адресом памяти.

а также какие значения вы получаете, вы уверены, что это адрес памяти?

Итак, пожалуйста, оставьте больше кода для более подробной информации

1 голос
/ 06 июня 2010
for (int i=0; i < 10; i++) {
    System.out.println("i: " + i + ", hashCode: " + new Object().hashCode());
}

печать:


i: 0, hashCode: 1476323068
i: 1, hashCode: 535746438
i: 2, hashCode: 2038935242
i: 3, hashCode: 988057115
i: 4, hashCode: 1932373201
i: 5, hashCode: 1001195626
i: 6, hashCode: 1560511937
i: 7, hashCode: 306344348
i: 8, hashCode: 1211154977
i: 9, hashCode: 2031692173
1 голос
/ 06 июня 2010

hashCode может и может быть переопределен используемым классом, JavaDoc для Object.hashCode () утверждает, что он '... обычно реализуется путем преобразования внутреннего адреса объекта вцелое число ... ', поэтому фактическая реализация может зависеть от системы.Обратите внимание также на третий момент в JavaDoc: два неравных объекта не обязаны возвращать разные hashCodes.

0 голосов
/ 06 июня 2010

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

...