使用方法比较两个类对象

时间:2015-11-12 03:37:47

标签: java class methods instance-variables

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

我需要制作一个比较两个对象并查看它们是否相等的方法。

非常感谢。

4 个答案:

答案 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的equalshashcode方法来比较同一类的两个不同对象

  

要比较的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 的两个对象。这意味着由于对象类中的equalshashcode方法无法满足我们的需要,我们得到了我们没想到的结果。 因此,在这种情况下,我们必须在 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

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