Как написать hashcode лучше, чем IDE



Метод hashcode используется, когда класс работает в качестве ключа в hash-based структурах данных. Следить за тем, как используется класс, не всегда удобно, поэтому есть правило — "Переопределяешь equals — переопредели hashcode".



Метод должен соблюдать контракт:



⭐️ Если объект не меняется, хэшкод остаётся постоянным

⭐️ У одинаковых объектов одинаковый хэшкод

⭐️ Если хэшкод одинаковый, то объекты не обязательно равны



Писать equals и hashcode вручную долго, поэтому часто используется автогенерация в IDE или Lombok аннотация @EqualsAndHashCode. Они создают что-то вроде



public int hashcode() {

return Objects.hash(id, param1, param2);

}



Что не так?



Контракт соблюдается, но суть хэшкода пропадает.



Хэшкод — это быстрая проверка без лишних вычислений. В коде выше результат вычисляется каждый раз на основе множества полей. А по количеству операций Objects.hashcode догоняет equals.



Как считать хэш быстрее:



1️⃣ Использовать одно поле



public int hashcode() {

return id;

}



2️⃣ Сохранять результат в отдельном поле



Подойдёт если у объекта нет id, и основные поля не меняются. Так сделано в классе String:



private int hash;



public int hashCode() {

int h = hash;

if (h==0 && !hashIsZero){

hash = …;

}

return h;

}



Эффект от оптимизации будет заметен, если класс активно участвует в hash-based структурах. В остальных случаях можно оставить автогенерацию.