2014-11-29 2 views
1

Предположим, мы имеем следующий класс:Java: Можно ли реализовать hashCode и равно для стороннего класса?

public class SingleElementRefType 
{ 

    protected JAXBElement<SequenceType> sequence; 

    // ... 
} 

Он содержит sequence поле типа JAXBElement.

JAXBElement класс третьей стороной (стандарт API, на самом деле), что, в сущности, чистый класс значение, но по какой-то причине не реализует hashCode и equals методы.

С моей точки зрения, эти методы здесь абсолютно разумны.

Я хотел бы реализовать equals и hashCode методы SingleElementRefType, а также SequenceType так, что я мог бы сделать глубокое сравнение этих значений. Но JAXBElement стоит на пути.

Поскольку я не могу продлить JAXBElement, моя идея состояла в том, чтобы интегрировать hashCode и equals в класс агрегирующего (SingleElementRefType здесь):

JAXBElement<SequenceType> theSequence; 
theSequence = this.getSequence(); 

final QName theSequenceName = theSequence.getName(); 
currentHashCode = ((currentHashCode* 37) + 
    ((theSequenceName!= null)?theSequenceName.hashCode(): 0)); 

final Object theSequenceValue = theSequence.getValue(); 
currentHashCode = ((currentHashCode* 37) + 
    ((theSequenceValue!= null)?theSequenceValue.hashCode(): 0)); 

Но тогда у меня был второй мысли, если я не нарушает какое-либо соглашение или правила здесь.

Существуют ли какие-либо опасности для реализации hashCode и equals для сторонних классов в моих агрегирующих классах?

Обновление: по каким-либо причинам у моего кода могут отсутствовать дополнительные зависимости от времени выполнения. Поэтому я не могу использовать Guava или commons-lang здесь.

+0

Это вполне разумная вещь, если вам это нужно; если вы используете Guava, вы можете использовать «Эквивалентность», см. [здесь] (http://javachannel.org/posts/guavas-equivalence-strategy-for-equalshashcode/). – fge

+0

@fge Невозможно использовать Guava здесь - мой код не должен иметь дополнительных зависимостей времени выполнения. Но хороший совет, я проверю концепцию. – lexicore

+0

Не мог ли содержащийся класс (я предполагаю, что это будет тот, который представляет другой элемент XML), позаботится о равных и хэш-кодах, просто обойдя JAXBElement? Я знаю, что xjc не включает эти методы, но плагин мог бы, и поэтому мог бы быть написанный вручную класс, когда элементу нужна оболочка JAXBElement. – laune

ответ

0

Совершенно разумно переопределить метод hashCode и equals вашего класса модели. Отменяя их, java указывает список контрактов, которым необходимо следовать.

Для равных,

  • возвратные [x.equals (х) = TRUE]
  • симметричные [x.equals (у) = истинно, то (y.equals (х) == истинные)]
  • переходных [x.equals (у) == истинные & & y.equals (г) == TRUE, то x.equals (г) == TRUE]
  • последовательные
  • «не- nullity '[x.equals (null) == false]

Для получения хэш-код,

  • консистенции: возвращать же целое число для того же объекта
  • , если (o1.equals (о2), то o1.hashcode == o2.hashcode)
  • not viceversa

Этот answer может предоставить вам представление о лучших практиках, которым необходимо следовать, в то время как overridin g hashCode().

И переопределение равно следовать этой практике:

  • Использования == для проверки, если аргумент является ссылкой на этот объект
  • Использования InstanceOf оператора, чтобы проверить, если аргумент имеет правильный тип
  • Вставьте аргумент в правильный тип
  • Для каждого «значимого» поля в классе проверьте, соответствует ли это поле аргумента соответствующему полю этого объекта

Способ, которым вы можете убедиться, что ваш переопределенный метод hashCode и equals эффективно выполняет контракты, будет проверять их с помощью Junits. Необходимость переопределения hashCode и equals будет более очевидной, когда в какой-то момент времени вам придется использовать свой модельный класс в хэш-коллекции, например, hashmap или hashset.

+1

Я не думаю, что это отвечает на вопрос. Автор, судя по их репутации SO, не просит учебника по equals и hashCode. – JamesB

+0

Я этого не замечал! то это должно быть так! – djames

Смежные вопросы