将对象设置为彼此相等(java)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30855198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:15:36  来源:igfitidea点击:

setting objects equal to eachother (java)

javamethodscompiler-errorsequals

提问by Idan Gelber

So I have a class called Person which looks like this

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

public class Person {

    private String personName;


    public String toString(){
        return personName;
    }

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

}

and another class in which I am creating the object(s) person

以及我在其中创建对象的另一个类人

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

    }

}

so far everything is fine and my print statement is
p1: Bob
p2: Joe

到目前为止一切都很好,我的打印语句是
p1:Bob
p2:Joe

Now I want to create a new object, p3 and set it equal to p1 my class now looks like this:

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

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

    }

}

when I try to do this I get the following error message:

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

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

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

I am thinking I will need to add a method to my main (Person) class, but I do not know why or what to add? why can't I just set the objects equal to eachother?

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

采纳答案by Mshnik

There are two ways to interpret "set the objects equal to each other".

有两种解释“将对象设置为彼此相等”的方法。

One is that you want p1and p3to refer to the sameobject. Like how Clark Kent and Superman are two names (references) for the same person. This would be accomplished by:

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

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

In this scenario, if anything happens to p1, that same thing has happened to p3. If you kill Clark Kent, you have killed Superman (as they are one and the same). Java determines equality with the equals(Object o)method - two objects aand bare equal iff a.equals(b)and b.equals(a)return true. These two objects will be equal using the base Objectdefinition of equality, so you don't have to worry about that.

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

The other way to interpret your meaning is to create a newperson object, which happens to be an exact copy of the first person. In order to do this, you'd have to add another constructor to your person class that takes a person as an argument:

解释你的意思的另一种方法是创建一个新的person 对象,它恰好是第一人称的精确副本。为了做到这一点,你必须向你的 person 类添加另一个构造函数,该类将一个 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;
    }

}

With this setup, you can do what you're doing in your main.

使用此设置,您可以在 main.js 中执行您正在执行的操作。

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

In order to make p1and p3equal, we have to teach the Person class to use its fields for checking equality. We can do this by overriding the equalsmethod in class person.

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

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

Whenever we overwrite the equalsmethod, it is good practice to also overwrite the hashcodemethod, which returns a unique intfor each Object. Since the only field that a Personobject has is its name, we can simply use that hashcode.

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

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

So all together, our Person class looks like this:

所以总的来说,我们的 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;
    }

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

回答by M Anouti

Person p3 = new Person(p1);

This is known as a copy constructor. You'll need to define it explicitly, in this case:

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

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

You also need to override the equals()method (and the hashCode()method) in order to use it, otherwise the equals()method of the root class Objectwould be used, which always returns false:

您还需要覆盖equals()方法(和hashCode()方法)才能使用它,否则将使用equals()根类的方法Object,它总是返回 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;
}

See What issues should be considered when overriding equals and hashCode in Java?.

请参阅在 Java 中覆盖 equals 和 hashCode 时应考虑哪些问题?.

回答by Mark W

If you want p3 to reference p2, meaning a change to p2 will update p3 and vice versa, just do

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

Person p3 = p2;

if you want to clone the data and have two distinct, but 'equal' copies of the person, you can implement a constructor in Person that takes a Person and copies the values into the classes fields.

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

回答by Hyman

No object in Java has a default copy constructor, with the exception of autoboxed objects like Floator Integerwhich are indeed copied.

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

This means that under all circumstances it's your duty to define a copy constructor and specify what is copied, in your example:

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

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

Since in Java everything is passed by reference a plain assignment would just make 2 variables point to the same instance, eg:

由于在 Java 中一切都是通过引用传递的,因此简单的赋值只会使 2 个变量指向同一个实例,例如:

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

回答by Yoni

It is because of your Person class constructor. You defined it to accept String type only and you gave it an object "p1" when you instantiate it. Editing the constructor or creating a new one will solve it.

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