Apache Commons equals/hashCode builder [已关闭]

我很想知道,这里的人们如何看待使用 / 来实现 /?这会比自己写更好吗?它与Hibernate配合得很好吗?你怎么看?org.apache.commons.lang.builderEqualsBuilderHashCodeBuilderequalshashCode


答案 1

commons/lang构建器很棒,我已经使用它们多年而没有明显的性能开销(有和没有休眠)。但正如阿兰所写,番石榴的方式甚至更好:

下面是一个示例 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或更高版本(受番石榴启发):

@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;
    }
}

注意:此代码最初引用了番石榴,但正如评论所指出的那样,此功能已在JDK中引入,因此不再需要番石榴。

如您所见,番石榴/ JDK版本更短,避免了多余的辅助对象。在相等的情况下,如果早期的调用返回false,它甚至允许短路评估(公平地说:commons / lang有一个具有相同语义的方法,可以使用而不是允许如上所述的短路)。Object.equals()ObjectUtils.equals(obj1, obj2)EqualsBuilder

所以:是的,公共语言构建器比手动构建和方法更可取(或者Eclipse将为您生成的那些可怕的怪物),但是Java 7 + / Guava版本甚至更好。equals()hashCode()

关于Hibernate的注释:

在 equals()、hashCode() 和 toString() 实现中使用惰性集合时要小心。如果您没有打开会话,这将失败得很惨。


注意(关于等于()):

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()

将超类合并到Guava Objects.hashcode()实现中的正确方法?

(虽然是关于 ,但同样适用于hashCode()equals())


注释(灵感来自kayahr的评论)

Objects.hashCode(..)(就像底层 )如果你有很多基元字段,可能会表现不佳。在这种情况下,实际上可能是更好的解决方案。Arrays.hashCode(...)EqualsBuilder


答案 2

伙计们,醒醒吧!从Java 7开始,标准库中有用于等于哈希码的帮助器方法。它们的使用完全等同于番石榴方法的使用。


推荐