我有很多用多个实例变量创建的对象(一个多个整数的字符串) 我必须创建一个方法来检查执行该方法的对象与另一个对象之间的相等性。我的意思是我想通过调用方法来查看两个对象的所有实例变量是否相同。我正在考虑像equals方法(string1.equals(string2))之类的东西,但是我可以对具有多个不是所有字符串的实例变量的对象做同样的事情吗?
示例:
//object1
String name1= keyb.nextLine();
int age1= keyb.nextInt();
int monthborn1;
//object2
String name2=keyb.nextLine();
int age2 = keyb.nextInt();
int monthborn2;
我需要制作一个比较两个对象并查看它们是否相等的方法。
非常感谢。
答案 0 :(得分:4)
是的,您可以为您的班级创建equals
方法。例如:
public final class Person {
private final String name;
private final int age;
private final int birthMonth;
public Person(String name, int age, int birthMonth) {
this.name = Objects.requireNonNull(name);
this.age = age;
this.birthMonth = birthMonth;
}
@Override
public boolean equals(Object o) {
if (o instanceof Person) {
Person rhs = (Person) o;
return name.equals(rhs.name)
&& age == rhs.age
&& birthMonth == rhs.birthMonth;
}
return false;
}
// Any time you override `equals`, you must make a matching `hashCode`.
// This implementation of `hashCode` is low-quality, but demonstrates
// the idea.
@Override
public int hashCode() {
return name.hashCode() ^ age ^ birthMonth;
}
}
答案 1 :(得分:2)
在Java中,您通常需要手动检查每个字段:
class MyObject {
String name;
int age, monthborn;
public boolean isEqual(MyObject other) {
return Objects.equals(name, other.name) &&
age == other.age && monthborn == other.monthborn;
}
}
此处使用的是 Objects.equals
,它与name.equals(other.name)
等效,为null。添加新字段时,您还必须在方法中添加新的检查。另一种方法是利用反射,但它看起来很丑陋并且具有显着的性能缺陷。这是一个草案示例如何执行此操作(不考虑可能的继承):
import java.lang.reflect.Field;
import java.util.Objects;
public class ObjectUtil {
public static <T> boolean allFieldsEqual(T o1, T o2) throws IllegalAccessException {
if(o1 == o2) return true;
if(o1.getClass() != o2.getClass()) return false;
for(Field field : o1.getClass().getDeclaredFields()) {
field.setAccessible(true);
if(!Objects.equals(field.get(o1), field.get(o2))) {
return false;
}
}
return true;
}
}
class MyObject {
String name;
int age, monthborn;
public boolean isEqual(MyObject other) {
try {
return ObjectUtil.allFieldsEqual(this, other);
} catch (IllegalAccessException e) {
return false;
}
}
}
这样,在添加新字段时,isEqual
方法也会将其考虑在内。但是,我不建议这样的解决方案。
答案 2 :(得分:0)
请参阅此answer。此外,由于您要覆盖equals方法,您还应该覆盖hashcode方法(也在链接的帖子中介绍)
答案 3 :(得分:0)
比较两个对象后,您必须考虑该类的所有成员。
我们假设我们有一个名为 B 的类,并且有两个成员变量年龄和名称。
B级:
public class B {
String name;
int age;
public B(String name, int age) {
this.age = age;
this.name = name;
}
}
然后让我们使用从{strong> 对象类 继承到我们的类B的equals
和hashcode
方法来比较同一类的两个不同对象
要比较的A类:
public class A {
public static void main(String args[]){
B b1 = new B("a", 22);
B b2 = new B("a",22);
System.out.println(b1.equals(b2));
System.out.println(b1.hashCode());
System.out.println(b2.hashCode());
}
}
一旦我们编译并运行A类,我们就会得到以下输出。
false
705927765//returns int value
366712642//returns int value
但是在A类中我们已经将相同的参数传递给 B 的两个对象。这意味着由于对象类中的equals
和hashcode
方法无法满足我们的需要,我们得到了我们没想到的结果。
因此,在这种情况下,我们必须在 B类中覆盖这些方法,以使其成功。
覆盖完成后的B类:
public class B {
String name;
int age;
public B(String name, int age) {
this.age = age;
this.name = name;
}
@Override
public boolean equals(Object obj) {
boolean flag = false;
if (obj instanceof B) {
B b = (B) obj;
if (this.age == b.age) {
if (this.name.charAt(0)==b.name.charAt(0))) {
flag = true;
} else {
flag = false;
}
} else {
flag = false;
}
} else {
flag = false;
}
return flag;
}
@Override
public int hashCode() {
return this.age+this.name.charAt(0);
}
}
如果我们再次运行A级,我们可以得到以下结果:
true
119
119
这意味着我们的工作已经完成。