比较具有大量属性的 class 的两个实例
Comparing two instances of class having big number of attributes
我有一个 class 有超过 30 个属性。
我想覆盖 equals 方法以便比较我的 class.
的两个实例
但是我想避免像这样重写我的方法中的所有 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);
}
你有更简单妥当的方法吗?
你在 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);
}
}
您可以使用 lombok 项目在构建时自动生成 hashCode 和 equals 方法。
您可以像这样在 java.lang.reflect
包中使用 Field
class:
@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
好吧,这基本上是必要的样板代码类型。幸运的是,有很多开发人员和您一样讨厌编写这样的代码。出于这样的原因,龙目岛项目成立了。
例如,请参阅从我上面链接的页面中提取的以下两个代码片段:
龙目岛
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;
}
}
}
原版 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 将不知道自动生成的方法。
您可以使用 Unitils 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"));
我有一个 class 有超过 30 个属性。
我想覆盖 equals 方法以便比较我的 class.
的两个实例但是我想避免像这样重写我的方法中的所有 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);
}
你有更简单妥当的方法吗?
你在 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);
}
}
您可以使用 lombok 项目在构建时自动生成 hashCode 和 equals 方法。
您可以像这样在 java.lang.reflect
包中使用 Field
class:
@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
好吧,这基本上是必要的样板代码类型。幸运的是,有很多开发人员和您一样讨厌编写这样的代码。出于这样的原因,龙目岛项目成立了。
例如,请参阅从我上面链接的页面中提取的以下两个代码片段:
龙目岛
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;
}
}
}
原版 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 将不知道自动生成的方法。
您可以使用 Unitils 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"));