设置对象彼此相等 (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 中的对象没有默认的复制构造函数,除了 Float
或 Integer
这样的自动装箱对象确实被复制了。
这意味着在任何情况下,您都有责任定义复制构造函数并指定要复制的内容,在您的示例中:
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"。
一个是您希望 p1
和 p3
引用 相同的 对象。就像克拉克肯特和超人是同一个人的两个名字(参考)一样。这将通过以下方式完成:
Person p1 = new Person("Jim");
Person p3 = p1;
在这种情况下,如果 p1
发生任何事情,p3
也会发生同样的事情。如果你杀了克拉克肯特,你就杀了超人(因为他们是同一个人)。 Java 用 equals(Object o)
方法确定相等 - 两个对象 a
和 b
相等当且仅当 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.
为了使 p1
和 p3
相等,我们必须教 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" 。编辑构造函数或创建一个新构造函数即可解决。
所以我有一个叫做 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 中的对象没有默认的复制构造函数,除了 Float
或 Integer
这样的自动装箱对象确实被复制了。
这意味着在任何情况下,您都有责任定义复制构造函数并指定要复制的内容,在您的示例中:
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"。
一个是您希望 p1
和 p3
引用 相同的 对象。就像克拉克肯特和超人是同一个人的两个名字(参考)一样。这将通过以下方式完成:
Person p1 = new Person("Jim");
Person p3 = p1;
在这种情况下,如果 p1
发生任何事情,p3
也会发生同样的事情。如果你杀了克拉克肯特,你就杀了超人(因为他们是同一个人)。 Java 用 equals(Object o)
方法确定相等 - 两个对象 a
和 b
相等当且仅当 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.
为了使 p1
和 p3
相等,我们必须教 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" 。编辑构造函数或创建一个新构造函数即可解决。