简体   繁体   English

如何重写子类的equals方法

[英]How to override the equals method of a subclass

I am trying to sync users between two different locations, therefore I keep existing users in a list, and hence do a comparison at a set time interval to see if the user should be added (new) or just updated. 我试图在两个不同位置之间同步用户,因此我将现有用户保留在列表中,并因此在设定的时间间隔进行比较,以查看是否应添加(新)或仅更新用户。

I have a class User that is the subclass to Principal. 我有一个类User,它是Principal的子类。

However my compare on the list does not work; 但是,我在列表上的比较不起作用; I googled a bit and found that you have to override the equals method, and I do - but that code does not seem to be executed, it goes into ArrayList.class (primitive) and executes the contains method there. 我在Google上搜索了一下,发现您必须重写equals方法,但是我确实做到了-但是该代码似乎没有执行,它进入ArrayList.class(原始)并在那里执行contains方法。

Is this because my class already extends the superclass Principal? 这是因为我的班级已经扩展了超类Principal吗? What are my options if I want to execute the equals that I defined in User class? 如果要执行在User类中定义的等式,我有哪些选择?

public class User extends Principal
{
    // some protected properties
    ...

        @Override
        public boolean equals(Object obj) {
            return (this.getAlias().equals(((User) obj).getAlias())
                && this.getEmailAddress().equals(((User) obj).getEmailAddress()) && this.getCellNumber().equals(((User) obj).getCellNumber()));
    } 
}

The Principal class does not override the equals method, and more importantly, the properties I check for equality, is only contained in the subclass - User. Principal类不会覆盖equals方法,更重要的是,我检查是否相等的属性仅包含在子类-User中。 Therefore it makes sense to check it here. 因此,在此处进行检查很有意义。

So in short, I have an ArrayList of Users, and I would like to check whether a certain User already exists or not. 简而言之,我有一个用户的ArrayList,我想检查某个用户是否已经存在。 I call compare on the list, but it always fails, indicative that the method equals is not overrided properly in my code. 我在列表上调用了compare,但是它始终失败,这表明我的代码中没有正确覆盖equals方法。 Any suggestions? 有什么建议么?

Overriding equals is not as evident as it looks 覆盖相等并不像看起来那样明显

  • equals with null must return false 等于null必须返回false
  • equals with an object of a different class must return false because of symetry a.equals(b) <=> b.equals(a) 与其他类的对象相等等于由于对称性必须返回false a.equals(b)<=> b.equals(a)

java 爪哇

@Override
public boolean equals(Object obj) {
    if (obj == this) {
        return true;
    }
    if (obj == null || obj.getClass()!=getClass()) {
        return false;
    }
    return Object.equals(this.getAlias(),((User) obj).getAlias())
        && Object.equals(this.getEmailAddress(),((User) obj).getEmailAddress())
        && Object.equals(this.getCellNumber(),((User) obj).getCellNumber()));
} 

Also if object is used in hash collections it must override hashCode so that two objects that are equals must return the same hashCode, the contrary is not true. 同样,如果在哈希集合中使用对象,则它必须覆盖hashCode,以便两个相等的对象必须返回相同的hashCode,事实并非如此。

You should not implement equals() (and hashcode() ) in a super class. 您不应该在超类中实现equals() (和hashcode() )。

The reason is that when equals() returns true hashcode() must return same value 原因是当equals()返回true时 hashcode() 必须返回相同的

Imagine you have class Point2D and class Point3D extending the other. 假设您有Point2D类和Point3D类扩展了另一个类。

Shall a point2D be equal to a point3D with same area coordinates? point2D是否等于面积坐标相同的point3D If so then point3D must return the same hashcode as the "equal" point2D and that means that you cannot not store more that one poin3d with same area coordinates in a Hash bases collection (eg.: as keys in a HashMap). 如果是这样,那么point3D必须返回与“等于” point2D相同的哈希 ,这意味着您不能在Hash bases集合中存储一个以上具有相同区域坐标的poin3d (例如:作为HashMap中的键)。

The problem probably comes from you instantiating a List<Person> . 问题可能出在您实例化List<Person> The compiler can't know if every subclasses of Person override equals . 编译器无法知道Person重写的每个子类是否equals To correct this, you should promise your compiler you'll override this method, which you can do by changing your Person class to an abstract class. 要纠正此问题,您应保证编译器将覆盖此方法,可以通过将Person类更改为抽象类来实现。

public abstract class Person {
    @Override
    public abstract boolean equals(Object o);
}

public class User extends Person {
    // Some stuff...
    @Override
    public boolean equals(Object o) {
        if (o == null || ! (o instanceof User))
            return false;
        // etc
    }
}

According to the book Effective Java.If you have override the equals method,then you must override the hashcode method. 根据有效Java一书中的内容。如果您覆盖了equals方法,则必须覆盖哈希码方法。 some advice when you override the equals method: 1. equals with null return false. 覆盖equals方法时的一些建议:1.等于null的返回false。 2. !(obj instanceof this) return false. 2.!(obj instanceof this)返回false。 3. cast obj to this class and compare the parameters in the obj and this class. 3.将obj转换为此类,并比较obj和此类中的参数。 return the result in the end 最后返回结果

You should use the contains methode of the arrayList 您应该使用arrayList的contains方法

https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM