override equals方法来比较java中的多个字段

在java中重写equals方法以比较多个字段的最佳方法是什么? 例如,我在类中有4个对象,o1,o2,o3,o4,我希望将所有这些对象与传递的对象进行比较,使用equals方法。

if (o1 != null && o2 != null && o3 != null && o4 != null && obj.o1 != null && obj.o2 != null && obj.o3 != null && obj.o4 != null && o1.equals(obj.o1) && o2.equals(obj.o2) && o3.equals(obj.o3) && o4.equals(obj.o4)) { do something } 

这段代码的问题在于它不清楚,如果我们有更多字段,就不能轻易修改。 有没有更好的方法来实现这一目标?

一种便宜的方式是:

 Arrays.asList(o1, o2, o3, o4).equals(Arrays.asList(obj.o1, obj.o2, obj.o3, obj.o4)); 

一件事是在实用程序类中有一个辅助方法:

 public static boolean equals(Object o1, Object o2) { if (o1 == o2) { return true; } if (o1 == null || o2 == null) { return false; } return o1.equals(o2); } 

然后你可以写:

 public boolean equals(Object other) { if (other == null || this.getClass() != other.getClass()) { return false; } Foo x = (Foo) other; return Helper.equals(o1, x.o1) && Helper.equals(o2, x.o2) && Helper.equals(o3, x.o3) && Helper.equals(o4, x.o4); } 

请注意,这样一来,当两个字段都为null时,它也会处理,而问题中的代码则不会。 (我说“应对” – 它给出的结果与Java的其余部分更加一致。)

您也可以为hashCode创建一个类似的辅助方法。

请注意, Guava已经在其Objects类中支持它(我确信许多其他实用程序库也会这样做)。

使用实用程序方法来帮助您

 private static boolean nullSafeEquals(Object o1, Object o2) { if(o1 == null && o2 == null) return true; // both null, both equal if(o1 == null || o2 == null) return false; // if one is null, not equal - we know both won't be null return o1.equals(o2); } public boolean equals(Object o) { if(o instanceof ThisClass) { ThisClass tc = (ThisClass)o; return nullSafeEquals(o1, tc.o1) && nullSafeEquals(o2, tc.o2) && nullSafeEquals(o3, tc.o3) && nullSafeEquals(o4, tc.o4); } return false; } 

使用番石榴 :

 @Override public boolean equals(final Object obj){ if (!(obj instanceof Foo)) { return false; } final Foo other = (Foo) obj; return Objects.equal(o1, other.o1) && Objects.equal(o2, other.o2) && Objects.equal(o3, other.o3) && Objects.equal(o4, other.o4); } 

你也可以获得便宜的hashCode():

 @Override public int hashCode() { return Objects.hashCode(o1, o2, o3, o4); } 

如果使用一个让你为你创建它。

我已经碰到了几次,最简单的方法是将所有比较的对象放入LinkedList,然后为您的Object编写一个客户比较器方法,该方法将接收该列表并运行它以查明是否它们等于传递的对象。 您甚至可能会发现LinkedList方法’contains()’将为您执行此操作,具体取决于您的对象。