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

我正在使用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; } } 

编辑:

进入inheritance并在这里有一个样本

如果我可以这样说的话, 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); 

顾名思义,由于instanceof运算符, equals调用将返回true。

我知道这听起来像基本的东西,而且大多数人都知道,但它很容易忘记它。 现在,如果您想要这种行为,那么没关系,您实现了正确的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很糟糕,不应该使用。 我只是说你必须意识到这种特殊情况,并决定是否将其考虑在内。

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

 new EqualsTester() .addEqualityGroup("hello", "h" + "ello") .addEqualityGroup("world", "wor" + "ld") .addEqualityGroup(2, 1 + 1) .testEquals(); 

它在番石榴测试笔记中。

  com.google.guava guava-testlib test  

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

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

它很好。 尽管instanceof使得null检查无关紧要。

此外,我认为使用自动生成的id很好,虽然这是非常 值得商榷的 。