commons/lang构建器非常棒,我已经使用了多年,没有明显的性能开销(有或没有hibernate).但正如阿兰所写的那样,番石榴的做法甚至更好:
下面是一个示例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)
.到HashCode();
}
@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或更高版本(受番石榴启发):
@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,但正如 comments 所指出的,这个功能已经在JDK中引入,所以Guava不再是必需的.
如您所见,Guava/JDK版本更短,并且避免了多余的辅助对象.在相等的情况下,如果较早的Object.equals()
调用返回False,它甚至允许短路计算(公平地说:Commons/Lang有一个具有相同语义的ObjectUtils.equals(obj1, obj2)
方法,可以使用该方法代替EqualsBuilder
来允许如上所述的短路).
因此:是的,Commons Lang构建器比手动构造的equals()
和hashCode()
方法(或者Eclipse将为您生成的那些可怕的怪物)更可取,但是Java7+/Guava版本甚至更好.
还有一条关于Hibernate的注释:
在equals()、hashCode()和到String()实现中使用惰性集合时要小心.如果你没有一个公开的会议,那将是惨败的.
注(关于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()){
If you use the second version, you probably also want 到 call super(equals())
inside your equals()
method. Opinions differ here, the 到pic is discussed in this question:
right way 到 incorporate superclass in到 a Guava Objects.hashcode() implementation?
(although it's about hashCode()
, the same applies 到 equals()
)
Note (inspired by Comment from 100)
如果有许多基本字段,Objects.hashCode(..)
(与底层Arrays.hashCode(...)
一样)可能会表现不佳.在这种情况下,EqualsBuilder
实际上可能是更好的解决方案.