使用方法比较两个 class 对象

Comparing two class objects with a method

我有很多对象是用多个实例变量创建的(一个字符串多个整数) 我必须创建一个方法来检查执行该方法的对象与另一个对象之间是否相等。我的意思是我想通过调用一个方法来查看两个对象的所有实例变量是否相同。我正在考虑类似于 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;

我需要创建一个方法来比较两个对象并查看它们是否相等。

非常感谢。

在 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) 的空安全等价物。当您添加新字段时,您还必须在您的方法中添加新检查。另一种方法是利用反射,但它看起来很丑并且有明显的性能缺陷。这是如何执行此操作的草稿示例(不考虑可能的继承):

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 方法也会将其考虑在内。但是我不推荐这样的解决方案。

请看这个answer。此外,由于您正在覆盖 equals 方法,因此您还应该覆盖 hashcode 方法(也包含在链接 post)

是的,您可以为 class 创建一个 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;
    }
}

一旦比较了两个对象,就必须考虑 class 的所有成员。

我们假设我们有一个名为 B 的 class 和两个成员变量 age姓名.

class B :

public class B {
    String name;
    int age;

    public B(String name, int age) {
        this.age = age;
        this.name = name;
    }
}

然后让我们使用 equalshashcode 方法比较相同 class 的两个不同对象,这些方法从 class B 继承class对象class.

class A to compare :

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());
    }
}

一旦我们编译 运行 class A 我们将得到以下输出。

false
705927765//returns int value
366712642//returns int value

但是在 class A 中,我们将相同的参数传递给 B 的两个对象。这意味着我们得到了我们没有预料到的结果,因为 Object class 中的 equalshashcode 方法没有做我们需要的事情。 所以在这种情况下,我们必须在 class B 中覆盖这些方法才能成功。

Class B after override done:

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);

    }
}

如果我们再次 运行 我们的 class A 我们可以得到以下结果:

true
119
119

这意味着我们的工作完成了。