我很好奇,这里的人们对使用org.apache.commons.lang.builder EqualsBuilder/ HashCodeBuilder 实施equals/有hashCode什么看法 ?比编写自己的方法更好的做法吗?它与Hibernate配合使用是否很好?你怎么看?
org.apache.commons.lang.builder
EqualsBuilder
HashCodeBuilder
equals
hashCode
commons / lang构建器很棒,我使用它们已有多年了,而没有明显的性能开销(带有和不带有hibernate状态)。但正如Alain所写,番石榴的方法更好:
这是一个示例Bean:
public class Bean{ private String name; private int length; private List<Bean> children; }
这是用Commons / Lang实现的equals()和hashCode():
@Override public int hashCode(){ return new HashCodeBuilder() .append(name) .append(length) .append(children) .toHashCode(); } @Override public boolean equals(final Object obj){ if(obj instanceof Bean){ final Bean other = (Bean) obj; return new EqualsBuilder() .append(name, other.name) .append(length, other.length) .append(children, other.children) .isEquals(); } else{ return false; } }
这里是Java 7或更高版本(受Guava启发):
@Override public int hashCode(){ return Objects.hash(name, length, children); } @Override public boolean equals(final Object obj){ if(obj instanceof Bean){ final Bean other = (Bean) obj; return Objects.equals(name, other.name) && length == other.length // special handling for primitives && Objects.equals(children, other.children); } else{ return false; } }
注意:此代码最初引用了Guava,但正如注释所指出的那样,此功能自JDK中引入以来,因此不再需要Guava。
如您所见,Guava / JDK版本较短,并且避免了多余的辅助对象。在相等的情况下,如果更早的Object.equals()调用返回false,它甚至可以使评估短路(公平地说:commons / lang有一种ObjectUtils.equals(obj1,obj2)具有相同语义的方法,可以用来代替EqualsBuilder上面的短路)。
Object.equals()
ObjectUtils.equals(obj1,obj2)
所以:是的,与手动构建的方法equals()和hashCode()方法(或Eclipse将为您生成的那些可怕的怪物)相比,公共语言生成器更可取,但是Java7+ / Guava版本更好。
equals()
hashCode()
还有关于hibernate的说明:
请注意在equals(),hashCode()和toString()实现中使用惰性集合。如果您没有公开的会议,那将惨遭失败。
注意(关于equals()):
a)在上述equals()的两个版本中,您可能还希望使用以下一个或两个快捷方式:
@Override public boolean equals(final Object obj){ if(obj == this) return true; // test for reference equality if(obj == null) return false; // test for null // continue as above
b)根据您对equals()合约的解释,您还可以更改行
if(obj instanceof Bean){
至
// make sure you run a null check before this if(obj.getClass() == getClass()){
如果使用第二个版本,则可能还需要super(equals())在equals()方法内部进行调用。意见分歧在此,在此问题中讨论主题:
super(equals())
将超类合并到GuavaObjects.hashcode()实现中的正确方法?
(尽管大约是hashCode(),这也适用于equals())
注意(灵感来自kayahr的评论)
Objects.hashCode(..)``Arrays.hashCode(...)如果您有许多原始字段,则(与底层一样)的性能可能会很差。在这种情况下,EqualsBuilder实际上可能是更好的解决方案。
Objects.hashCode(..)``Arrays.hashCode(...)