Java: автоматическое equals () и hashCode () - PullRequest
17 голосов
/ 05 августа 2011

Реализация equals() и hashCode() для простых данных POJO загромождают мой код, и обслуживание утомительно.

Какие библиотеки обрабатывают это автоматически?
Я предпочитаю инструментарий байт-кода по сравнению с подходом AOP из-засоображения производительности.

Обновление: Обсуждалась тема необходимости реализации equals () и hashCode (), вот мое мнение:

Не лучше ли иметьвсе сделано правильно с минимальными усилиями, вместо того, чтобы копаться в коде, добавляя hC / eq, когда дело доходит до этого?

Ответы [ 5 ]

12 голосов
/ 05 августа 2011

Project Lombok предоставляет аннотацию @ EqualsAndHashCode , которая сгенерирует equals() и hashCode() для ваших классов Java.Конечно, есть некоторые недостатки по сравнению с ручной реализацией этих методов, поэтому обязательно прочитайте «мелкий шрифт» на связанной странице.

3 голосов
/ 05 августа 2011

Как насчет Гуавы х Objects.hashCode и Objects.equal?

2 голосов
/ 26 сентября 2014

Вы можете использовать библиотеку Google AutoValue для автоматического создания классов неизменяемых значений с equals и hashCode. Эти классы значений чем-то похожи на классы дел в Scala или на классы, сгенерированные Lombok

Также есть пост о том, как использовать его в IDE.

1 голос
/ 04 октября 2018

Java 7 и более поздние версии

Несмотря на то, что вы не запрашивали панацею, написание переопределения hashCode теперь немного проще, чем в Java 7 и более поздних версиях.

Objects.hashCode & Objects.hash

Начиная с Java 7, класс Objects предлагает несколько вспомогательных методов для генерации значений хеш-кода.

См. мой ответ по связанному Вопросу для дальнейшего обсуждения.

  • Если ваше переопределение hashCodeequals) основано на одном члене вашего класса, используйте Objects.hashCode( member ).
  • Если ваше переопределение hashCodeequals) основано на нескольких атрибутах вашего класса, используйте Objects.hash( memberA , memberB , memberC ).

Один элемент, не допускающий NULL

@Override
public int hashCode() {
    return this.member.hashCode() ;  // Throws NullPointerException if member variable is null.
}

Один элемент, допускающий NULL

@Override
public int hashCode() {
    return Objects.hashCode( this.member ) ;  // Returns zero (0) if `this.member` is NULL, rather than throwing exception.
}

Multi-member

@Override
public int hashCode() {
    return Objects.hash( this.memberA , this.memberB , this.memberC  ) ;  // Hashes the result of all the passed objects’ individual hash codes.  
}
1 голос
/ 05 августа 2011

В библиотеке Apache commons-lang есть HashCodeBuilder и EqualsBuilder, которые сделают часть работы за вас и сократят эти методы. Есть даже версии отражений, которые сделают все это за вас, основываясь на полях в POJO. Однако я бы не рекомендовал это. Отражение может быть медленным (хотя и не таким плохим, как думают многие), и вы должны реализовать их, чтобы быть уверенными, что только правильные поля считаются равными.

Мой вопрос: тебе действительно нужно это сделать? Часто хеш-код и эквивалентные значения для POJO необходимо реализовать только для использования с картами или наборами. В случае с картами обычно вы используете идентификатор для ключа, который не является самим Pojo. Итак ... ты работаешь на себя?

...