我是否使用Google Guava正确实现了equals和hashCode?

bra*_*ter 10 java equals hashcode guava

我正在使用hibernate并需要覆盖equals和hashCode().我选择使用google-guava的equals和hashCode助手.

我想知道我在这里是否遗漏了什么.

我有id/imagefilePath的 get/set方法.

@Entity
@Table(name = "IMAGE")
public class ImageEntity {
    private Integer idImage;
    private String filePath;

    @Override
    public int hashCode() {
        return Objects.hashCode(getFilePath());
    }

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

        if(obj instanceof ImageEntity){
            final ImageEntity otherImage = (ImageEntity) obj;
            return Objects.equal(getFilePath(), otherImage.getFilePath());
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

进入继承并在这里有一个样本

Rad*_*zea 18

instanceof运营商的问题是,如果我可以这么说,它会考虑到多态性.

比方说,例如,你这样做:

public class AdvancedImageEntity extends ImageEntity
{
    //some code here
}
Run Code Online (Sandbox Code Playgroud)

然后你这样做:

ImageEntity ie = new ImageEntity ();
AdvancedImageEntity advanced_ie = new AdvancedImageEntity ();

boolean this_will_be_true = ie.equals (advanced_ie);
Run Code Online (Sandbox Code Playgroud)

顾名思义,equals由于instanceof操作员,该调用将返回true .

我知道这听起来像基本的东西,而且大多数人都知道,但它很容易忘记它.现在,如果您想要这种行为,那就没问题,您已equals正确实施.但是如果你认为一个ImageEntity对象不能等于一个(假设的)AdvancedImageEntity对象,那么要么声明ImageEntityfinal忘记instanceof并实现你的equals方法,如下所示:

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

    if (getClass ().equals (obj.getClass ()))
    {
        final ImageEntity otherImage = (ImageEntity) obj;

        return Object.equals (getFilePath(), otherImage.getFilePath());
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

无论引用的类型是什么,这都将检查对象的真实类型.如果obj参数是子类的实例,它将"滑动" instanceof.但是getClass要严格得多,不会允许它.

PS:我不是说这instanceof很糟糕,不应该使用.我只是说你必须意识到这种特殊情况,并决定是否使用它考虑到这一点.


Tho*_*ung 12

您实际上可以使用Guava EqualsTester来测试您的equals和hashCode实现:

new EqualsTester()
     .addEqualityGroup("hello", "h" + "ello")
     .addEqualityGroup("world", "wor" + "ld")
     .addEqualityGroup(2, 1 + 1)
     .testEquals();
Run Code Online (Sandbox Code Playgroud)

它在番石榴testlib中.

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava-testlib</artifactId>
    <scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)

对您的实施进行细微更改:

@Override public boolean equals(final Object obj) {
    if(obj == this) return true;
    return obj instanceof ImageEntity &&
        Objects.equal(getFilePath(), ((ImageEntity) obj).getFilePath());
}
Run Code Online (Sandbox Code Playgroud)