我有一个超过30个属性的类。
我想覆盖equals方法,以便比较我的类的两个实例。
但是我想避免在我的方法中重写所有30个属性
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Address address = (Address) o;
return Objects.equals(this.attr1, address.attr1) &&
Objects.equals(this.attr2, address.attr2) &&
Objects.equals(this.attr3, address.attr3) &&
......
Objects.equals(this.attr30, address.attr30);
}
你有一个更简单和正确的方法吗?
答案 0 :(得分:2)
你在apache commons库中有这个方法,它使用反射来比较它们
org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals(Object, Object)
实施例
import org.apache.commons.lang.builder.EqualsBuilder;
public class MyObject {
...
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
}
答案 1 :(得分:2)
您可以使用lombok项目在构建时自动生成hashCode和equals方法。
答案 2 :(得分:2)
您可以使用Field
包中的java.lang.reflect
类,如下所示:
@Override
public boolean equals(Object o) {
//instanceof check, null check, etc
Field[] fields = Address.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
if (!field.get(this).equals(field.get((Address) o))) {
return false;
} //end if
} catch (IllegalAccessException e) {
//handle exception
} //end try catch
} //end for
return true;
} //equals
答案 3 :(得分:2)
嗯,这基本上是必要的样板代码类型。幸运的是,有很多开发人员对编写此类代码感到恼火。出于这样的原因,Project Lombok成立了。
例如,请参阅我在上面链接的页面中提取的以下两个代码段:
<强>龙目强>
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(exclude={"id", "shape"})
public class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
public String getName() {
return this.name;
}
@EqualsAndHashCode(callSuper=true)
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
}
}
Vanilla Java
import java.util.Arrays;
public class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
public String getName() {
return this.name;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof EqualsAndHashCodeExample)) return false;
EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;
if (!other.canEqual((Object)this)) return false;
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
if (Double.compare(this.score, other.score) != 0) return false;
if (!Arrays.deepEquals(this.tags, other.tags)) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
final long temp1 = Double.doubleToLongBits(this.score);
result = (result*PRIME) + (this.name == null ? 43 : this.name.hashCode());
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.tags);
return result;
}
protected boolean canEqual(Object other) {
return other instanceof EqualsAndHashCodeExample;
}
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Square)) return false;
Square other = (Square) o;
if (!other.canEqual((Object)this)) return false;
if (!super.equals(o)) return false;
if (this.width != other.width) return false;
if (this.height != other.height) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
result = (result*PRIME) + super.hashCode();
result = (result*PRIME) + this.width;
result = (result*PRIME) + this.height;
return result;
}
protected boolean canEqual(Object other) {
return other instanceof Square;
}
}
}
如果您喜欢这种方法,我建议您完整地查看Project Lombok。它真的有助于清理你的代码!
<强> !!!小心!!! 为了能够实际使用Lombok生成的方法,您需要将Lombok插件安装到IDE中!否则,您的IDE不会知道自动生成的方法。
答案 4 :(得分:1)
您可以使用单位http://www.unitils.org/cookbook.html
import static org.unitils.reflectionassert.ReflectionAssert.*;
// Exact field-by-field comparison
assertReflectionEquals(new Person("John", "Doe", new Address("New street", 5, "Brussels")),
new Person("John", "Doe", new Address("New street", 5, "Brussels"));