2014-12-10 1 views
1

У меня есть класс со многими (около 100) полями. Я хочу реализовать методы hashCode() и equals() для этих полей, есть ли альтернатива этому вручную?Создание методов .hashcode() и .equals() для большого объекта

+6

100 - сумасшедшее количество полей для одного класса ... рассмотрите рефакторинг. – August

+2

eclipse может автоматически генерировать эти методы для вас – chris

+1

Вы должны сначала перезаписать свой класс. Я не могу думать ни о какой сущности, кроме БОГА, чтобы иметь 100 собственных атрибутов ;-) –

ответ

0

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

+0

Создание хэш-кода во всех 100+ полях почти наверняка неверно, так как многие из них будут изменчивыми. Я думаю, вы могли бы использовать Eclipse для запуска, а затем удалить многие из них. – user949300

+0

@ user949300 yes eclipse будет легко создавать код, тогда мы легко будем манипулировать им. –

4

Нет отличного ответа. Вот несколько советов. Как прокомментировали другие, 100 полей слишком много. Лучше всего реорганизовать класс. Но, если вы должны держать все это вместе:

  • Вы могли бы использовать Map (или другой коллекции) провести много полей?

Если это так, вы можете использовать их встроенные методы hashCode() и equals(). (Или гуавы и т.д., как указывал @ dimo414)

  • хэш-код() следует рассматривать только неизменяемые поля (или, по крайней мере, полей, которые редко редко меняются.)

Если только несколько ваши поля неизменяемы, что значительно упростит ваш код hashCode(). И, что более важно, сделайте это правильно. :-)

  • С 100+ полями, что реалистический шанс, что два экземпляра будут когда-либо быть равны?

Если ответ «крайне редко», спросите себя, можете ли вы избежать использования базового равенства Object (по сути, используя ==)?

  • У Вас уже есть информативный ToString() метод?

Если да, то вы можете иногда использовать эту строку как неэффективные, но легко коду, хэш-код() и равенство(). например .:

public int hashCode() { return this.toString().hashCode(); } 

public boolean equals(Object o) { 
    return (o instanceof MyClass) && 
      (this.toString().equals(o.toString())); 
} 
+0

Если изменение объекта изменяет набор других объектов, к которым он может сравниться, то для такой модификации это нормально влияет на значение hashCode().В общем случае незаконно для объектов хранить ссылку на что-то на карте, а затем - пока карта по-прежнему содержит ссылку, модифицирует ее так, чтобы она сравнялась с вещами, которые она не делала ранее, или наоборот. Хотя код мог бы изменять объекты, хранящиеся на карте, без нарушения вышеуказанного ограничения, если бы они знали, что карта никогда не увидит, что два объекта сравниваются равными ... – supercat

+0

... в свое время и неравномерно в какое-то другое время , и изменение хеш-кода приведет к сломанию карты в ситуации, когда бы хэш-код оставался прежним, сработало бы, большинство кода, который правильно использует карты, не должны волновать, влияют ли изменения, влияющие на равенство, на хэш-код. – supercat

1

Другие указывали на то, что объект этот большой, вероятно, не большой образец для подражания, поэтому я предполагаю, что вы знаете, что уже и решили продолжить в любом случае. Я также предполагаю, что этот объект является (в основном) неизменным, так как реализация .hashCode() для изменяемых объектов обычно является плохим планом (по крайней мере, вы должны быть осторожны при установке изменяемых объектов в HashSet или в виде ключей в HashMap).

Если у вас есть класс с большим количеством полей, которые можно избежать определения комплекса .hashCode(), .equals() и .toString() методы, пользуясь существующей функциональности, которая делает то же самое.Легкий вариант состоит в том, чтобы построить List или Map ваших полей и просто вызвать соответствующие методы Collection. Вы даже можете кэшировать возвращаемые значения этих функций, а не удерживать их на целом Collection, если хотите.

Существует также множество полезных утилит, облегчающих эти методы; есть слишком много, чтобы перечислить, но я буду стараться, чтобы вызвать пару особенно полезных из них:

Кроме того, вы можете use reflection to get all the fields в вашем объекте во время выполнения. Это будет медленнее, чем жестко закодированная реализация, но, скорее всего, будет быстрее писать. Если вы не слишком обеспокоены скоростью, это хороший вариант.

0

Хотя не очень хорошая практика иметь объект с таким количеством полей, иногда устаревшие ограничения ловят вас в плохую ситуацию.

Независимо от размера, я нахожу самый простой способ переопределить эти методы, используя библиотеку сообщества Apache. Он использует отражение для генерации значений из экземпляра и существует множество способов настройки результатов. Мне также не нужно запоминать, чтобы восстановить этот метод, если обновление полей, в отличие от методов сгенерированных затмений.

@Override 
public final boolean equals(final Object obj) { 
    if (obj == this) { 
     return true; 
    } 

    if(obj != null && obj.getClass() == this.getClass()) { 
     return EqualsBuilder.relectionEquals(this, obj, true); 
    } 

    return false; 
} 

@Override 
public final int hashCode() { 
    return HashCodeBuilder.relectionHashCode(this); 
} 

@Override 
public final String toString() { 
    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); 
} 
Смежные вопросы