Подскажите пожалуйста, должен ли Hashcode объекта измениться если его поля изменились?
Ни фига не должен, смотрим сюда:
public class HelloWorld {
public static void main(String[] args) {
//создаем объект
MyMutable myMutable = new MyMutable(1, "Hello");
System.out.println("intValue="+myMutable.getIntValue()+", stringValue="+myMutable.getStringValue()+", hashcode="+myMutable.hashCode());
//мутируем (меняем) его свойства
myMutable.setIntValue(2);
myMutable.setStringValue("World!");
//проверяем hashCode()
System.out.println("intValue="+myMutable.getIntValue()+", stringValue="+myMutable.getStringValue()+", hashcode="+myMutable.hashCode());
}
}
class MyMutable {
private int intValue;
private String stringValue;
public MyMutable(int intValue, String stringValue) {
this.intValue=intValue;
this.stringValue=stringValue;
}
public void setIntValue(int intValue) {
this.intValue=intValue;
}
public int getIntValue() {
return this.intValue;
}
public void setStringValue(String stringValue) {
this.stringValue=stringValue;
}
public String getStringValue() {
return this.stringValue;
}
}
Вывод:
intValue=1, stringValue=Hello, hashcode=1829164700
intValue=2, stringValue=World!, hashcode=1829164700
Специально ввел 2 разных поля, все равно при их изменении hashCode()
не пересчитывается и остается прежним.
Update
по следам дискуссии в комментариях:
1) В дефолтной реализации hashCode()
он не будет меняться при мутации объекта
2) Чтобы он менялся необходимо переопределять hashCode()
, например для приведенного примера приблизительно так:
public int hashCode() {
return super.hashCode()+
this.intValue+
((this.stringValue==null?0:this.stringValue.hashCode());
}
https://habr.com/post/168195/
Одинаковые объекты — это объекты одного класса с одинаковым содержимым полей.
Если объекты одинаковые, то и хеш-коды одинаковые (но не наоборот, см. правило 3).
Да, должен. Вот что по этому поводу пишут в документации:
The general contract of hashCode is:
Это следует из второго пункта и выделенной части первого. Но стоит иметь ввиду, что реализация по умолчанию метода hashCode
этим принципам не следует, поэтому её всегда надо переопределять.
Все просто:
Если при описании своего объекта вы не переопределяете метод hashcode, то при его инициализации(вызов new) ему присваивается идентификационный хеш - hash по умолчанию. Делается это при помощи стандартного нативного метода.
В этом случае поля вашего объекта никак не влияют на формирование hashcode, соответственно любые изменения этих полей не приведут к изменению hashcode. Стоит учитывать, что создание нового аналогичного объекта не гарантирует совпадение hashcode
Если же вы явно переопределили метод hashcode и вычисление hash - объекта завязали на значение своих полей, то при их изменении hashcode так же изменится
Правильнее было бы использовать примерно такую модель, коль вы решили использовать собственный калькулятор хеша:
public class Test
{
private int _a;
private int _b;
private int _c;
public Test(int a, int b, int c)
{
_a = a;
_b = b;
_c = c;
}
@Override
public int hashCode()
{
return _a ^ _b ^ _c;
}
}
И не обязательно возвращать сгенерированный самой JVM хешкод объекта при запросе через super.hashcode()
, если изменилось какое-то условие. На мой взгляд это моветон.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как усовершенствовать метод удаления заполненных линий? Чтобы заполненная линия изменялась на конкретную текстуру из класса Assets, а потом...
Как можно смаппить поле из типа определенным пользователем с полем в java со spring data
помогите разобраться, хочу сделать background (добивать изображение на основной фон), собственно добавление идет строками
Необходимо получить все данные игрока из базы данных, для проверки насколько это быстро произойдет я создал цикл из 100 юзеров