设置对象彼此相等 (java)

setting objects equal to eachother (java)

所以我有一个叫做 Person 的 class 看起来像这样

public class Person {

    private String personName;


    public String toString(){
        return personName;
    }

    public Person(String personName){
        this.personName = personName;
    }

}

和另一个 class,我正在其中创建对象

public class IdanJavaTask {

    public static void main(String[] args) {

        Person p1 = new Person("Bob");
        System.out.println("p1 : " + p1);

        Person p2 = new Person("Joe");
        System.out.println("p2 :" + p2);

    }

}

到目前为止一切正常,我的打印语句是
p1: 鲍勃
p2:乔

现在我想创建一个新对象 p3 并将其设置为等于 p1 我的 class 现在看起来像这样:

public class IdanJavaTask {

    public static void main(String[] args) {

        Person p1 = new Person("Bob");
        System.out.println("p1 : " + p1);

        Person p2 = new Person("Joe");
        System.out.println("p2 :" + p2);

        Person p3 = new Person (p1);
        System.out.println("p3 equal to p1:" + p3.equals(p1));

    }

}

当我尝试这样做时,我收到以下错误消息:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    The constructor Person(Person) is undefined

    at vehicleassignment.IdanJavaTask.main(IdanJavaTask.java:13)

我想我需要向我的主要(人)添加一个方法 class,但我不知道为什么或要添加什么?为什么我不能将对象设置为彼此相等?

Person p3 = new Person(p1);

这称为复制构造函数。您需要明确定义它,在这种情况下:

public Person(Person p) {
    this.personName = p.personName;
}

你还需要覆盖equals()方法(和hashCode()方法)才能使用它,否则根class的equals()方法Object 将被使用,它总是 returns false:

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (personName == null) {
        if (other.personName != null)
            return false;
    } else if (!personName.equals(other.personName))
        return false;
    return true;
}

参见 What issues should be considered when overriding equals and hashCode in Java?

如果您希望 p3 引用 p2,这意味着对 p2 的更改将更新 p3,反之亦然,只需这样做

Person p3 = p2;

如果您想克隆数据并拥有两个不同但 'equal' 人的副本,您可以在 Person 中实现一个构造函数,该构造函数接受一个人并将值复制到 类字段。

Java 中的对象没有默认的复制构造函数,除了 FloatInteger 这样的自动装箱对象确实被复制了。

这意味着在任何情况下,您都有责任定义复制构造函数并指定要复制的内容,在您的示例中:

public Person(Person other) {
  this.personName = other.personName;
}

因为在 Java 中所有东西都是通过引用传递的,一个简单的赋值只会让 2 个变量指向同一个实例,例如:

Person p1 = new Person("Joe");
Person p2 = p1;
// now both point to the same object, not intended behavior in your case

有两种解读方式"set the objects equal to each other"。

一个是您希望 p1p3 引用 相同的 对象。就像克拉克肯特和超人是同一个人的两个名字(参考)一样。这将通过以下方式完成:

Person p1 = new Person("Jim");
Person p3 = p1;

在这种情况下,如果 p1 发生任何事情,p3 也会发生同样的事情。如果你杀了克拉克肯特,你就杀了超人(因为他们是同一个人)。 Java 用 equals(Object o) 方法确定相等 - 两个对象 ab 相等当且仅当 a.equals(b)b.equals(a) return true。使用基本 Object 相等性定义,这两个对象将相等,因此您不必担心这一点。

另一种解释您的意思的方法是创建一个 new 人物对象,它恰好是第一人称的精确副本。为此,您必须向您的 person class 添加另一个构造函数,它将 person 作为参数:

public class Person {

    private String personName;

    public String toString(){
        return personName;
    }

    public Person(String personName){
        this.personName = personName;
    }

    public Person(Person personToCopy){
        this.personName = personToCopy.personName;
    }

}

通过此设置,您可以在主程序中执行您正在执行的操作。

Person p1 = new Person("Bob");
Person p3 = new Person(p1); //Will have name Bob.

为了使 p1p3 相等,我们必须教 Person class 使用其字段来检查相等性。我们可以通过覆盖 class 人中的 equals 方法来做到这一点。

public boolean equals(Object o){
    if(! (o instanceof Person)) return false; //a Person can't be equal to a non-person

    Person p = (Person) o;
    return personName == null && p.personName == null || personName.equals(p.personName);
}

每当我们覆盖 equals 方法时,最好也覆盖 hashcode 方法,return 是每个对象的唯一 int。由于 Person 对象的唯一字段是它的名称,我们可以简单地使用该哈希码。

public int hashCode(){
    return personName == null ? 0 : personName.hashCode();
}

总而言之,我们的人 class 看起来像这样:

public class Person {

    private String personName;

    public String toString(){
        return personName;
    }

    public Person(String personName){
        this.personName = personName;
    }

    public Person(Person personToCopy){
        this.personName = personToCopy.personName;
    }

    public boolean equals(Object o){
        if(! (o instanceof Person)) return false; //a Person can't be equal to a non-person

        Person p = (Person) o;
        return personName == null && p.personName == null || personName.equals(p.personName);
    }

    public int hashCode(){
        return personName == null ? 0 : personName.hashCode();
    }
}

这是因为你的 Person class 构造函数。您将其定义为仅接受 String 类型,并在实例化时给了它一个对象 "p1" 。编辑构造函数或创建一个新构造函数即可解决。