我正在使用hibernate并需要覆盖equals和hashCode()。我选择使用google-guava的equals和hashCode助手。
我想知道我在这里遗失了什么。
我已获取/设置 idImage 和 filePath 的方法。
@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;
}
}
修改
进入继承并获得样本here
答案 0 :(得分:18)
instanceof
运算符的问题在于,如果可以这么说,它会考虑多态性。
例如,假设您执行此操作:
public class AdvancedImageEntity extends ImageEntity
{
//some code here
}
然后你这样做:
ImageEntity ie = new ImageEntity ();
AdvancedImageEntity advanced_ie = new AdvancedImageEntity ();
boolean this_will_be_true = ie.equals (advanced_ie);
顾名思义,equals
调用将返回true,因为instanceof
运算符。
我知道这听起来像是基本的东西,而且大多数人都知道,但是很容易忘记它。现在,如果您想要这种行为,那么没关系,您正确实施了equals
。但是如果你认为ImageEntity
对象不能等于(假设的)AdvancedImageEntity
对象,那么要么ImageEntity
声明为final
要么忘记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;
}
这将检查对象的真实类型,无论引用的类型是什么。如果obj
参数是子类的实例,它将“滑动”instanceof
。但getClass
更加严格,不会允许它。
PS:我不是说instanceof
是坏的,不应该使用。我只是说你必须意识到这种特殊情况,并决定是否使用它考虑到这一点。
答案 1 :(得分:12)
您实际上可以使用Guava EqualsTester来测试您的equals和hashCode实现:
new EqualsTester()
.addEqualityGroup("hello", "h" + "ello")
.addEqualityGroup("world", "wor" + "ld")
.addEqualityGroup(2, 1 + 1)
.testEquals();
它在番石榴测试笔中。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
<scope>test</scope>
</dependency>
对您的实施进行细微更改:
@Override public boolean equals(final Object obj) {
if(obj == this) return true;
return obj instanceof ImageEntity &&
Objects.equal(getFilePath(), ((ImageEntity) obj).getFilePath());
}
答案 2 :(得分:3)