Согласно документации 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 может быть положительным или отрицательным.