如何覆盖对象类中的equals方法?
即我有:
class Person{
//need to override here
public boolean equals (Object obj){
}
我想将参数obj转换为Person类型,但如果我使用(Person) obj就行不通。
实际上比你想象的更加复杂。让Eclipse(或者你使用的任何IDE)自动生成一个equals
方法,你会看到它在进行比较之前包含几个检查和转换。
另请参见:http://www.javapractices.com/topic/TopicAction.do?Id=17
您可以在方法内部进行转换,只需确保使用instance of是正确的类型即可。
if(obj instanceof Person)
{
Person otherPerson = (Person) obj;
//Rest of the code to check equality
}
else
{
//return false maybe
}
@Override
public boolean equals(Object o)
{
if (o instanceof Person)
{
Person c = (Person) o;
if ( this.FIELD.equals(c.FIELD) ) //whatever here
return true;
}
return false;
}
@Override
。 - Tom Hawtin - tackline请查看关于对象比较的问题。
请注意,如果您覆盖了equals()
方法,则必须同时覆盖hashCode()
方法。equals/hashCode合同是,如果两个对象相等,则它们必须具有相同的哈希码。
new Employee().equals(new Person())
将会是 false(Person 不是 Employee 的实例)。如果你颠倒参数,结果必须相同,因此一个 Person 不能等于它自己的子类(除非在子类的 equals()
方法中做了一些非常奇怪的事情)。 - Andrzej Doyleif(obj!=null && obj.getClass() == this.getClass())
,因为这样可以在子类继承时正常工作。目前你回答中的示例会导致子类的实例不等于它本身(除非它重写了equals()方法),这也是错误的。 - Andrzej DoylegetClass()
而不是instanceof
。Employee
e和一个Manager
m(扩展自Employee
)。
m instanceof Employee
将返回true,m.getClass() == Employee.class
将返回false。equals()
或hashCode()
方法中比较实例。对于任何字段类型,我更喜欢更简单、空安全的Objects.equals
:
@Override
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
return Objects.equals(p.FIELD, this.FIELD);
}
return false;
}
还有一个需要了解的重点是,当你覆盖equals()
方法(以及hashcode()
方法)后,你可以像下面这样比较同一类的两个对象:
Person p1 = new Person();
Person p2 = new Person();
....
if ( p1.equals( p2 ) )
{
// --- Two Persons are equal, w.r.t the fields you specified in equals method ---
}
我知道这个问题已经有答案了,但在我的实践中,我发现这是覆盖对象比较以确保全局一致性的最有效方法:
@Override
public boolean equals(Object o) {
return o instanceof Person && this.getSomeMagicalField().equals(((Person) o).getSomeMagicalField());
}
或者如果你不是在比较字符串:
@Override
public boolean equals(Object o) {
return o instanceof Person && this.getSomeMagicalField() == (Person) o).getSomeMagicalField();
}
obj.getClass() == Person
而不是instanceof Person
来检查运行时类。虽然可以编写使派生类型相等的合同(如java.util.List
),但需要谨慎。此外,如果您重写了equals
,则应该覆盖hashCode
,但这可能有点超前。 - Tom Hawtin - tackline