Ответ
При использовании Lombok (@EqualsAndHashCode) для генерации equals() и hashCode() необходимо соблюдать общий контракт Object.equals():
- Рефлексивность:
x.equals(x)всегдаtrue. - Симметричность: Если
x.equals(y) == true, тоy.equals(x)также должно бытьtrue. - Транзитивность: Если
x.equals(y)иy.equals(z), тоx.equals(z). - Согласованность: Многократные вызовы
x.equals(y)должны возвращать одно и то же значение, если поля, участвующие в сравнении, не менялись. - Сравнение с null:
x.equals(null)всегдаfalse.
Особенности Lombok:
- Аннотация
@EqualsAndHashCodeпо умолчанию включает все нестатические, нетранзиентные поля. - Ключевое правило: Lombok автоматически обеспечивает согласованность с
hashCode(), генерируя оба метода на основе одного набора полей.
Управление полями:
// Включить только явно помеченные поля
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User {
@EqualsAndHashCode.Include
private Long id; // Участвует в equals/hashCode
private String name; // НЕ участвует
@EqualsAndHashCode.Exclude
private String email; // Явно исключено
}
Почему важно: Нарушение контракта, особенно симметричности и транзитивности, приводит к непредсказуемому поведению коллекций (HashSet, HashMap).