Java 如何重写子类的equals方法

Java 如何重写子类的equals方法,java,arraylist,compare,overriding,equals,Java,Arraylist,Compare,Overriding,Equals,我试图在两个不同的位置之间同步用户,因此我将现有用户保留在一个列表中,并因此在设置的时间间隔内进行比较,以查看是否应该添加(新)用户或只是更新用户 我有一个类User,它是Principal的子类 但是,列表中我的比较不起作用;我在谷歌上搜索了一下,发现您必须重写equals方法,我确实是这样做的——但代码似乎没有被执行,它进入ArrayList.class(primitive)并在那里执行contains方法 这是因为我的类已经扩展了超类主体吗? 如果我想执行我在用户类中定义的等式,我的选项是

我试图在两个不同的位置之间同步用户,因此我将现有用户保留在一个列表中,并因此在设置的时间间隔内进行比较,以查看是否应该添加(新)用户或只是更新用户

我有一个类User,它是Principal的子类

但是,列表中我的比较不起作用;我在谷歌上搜索了一下,发现您必须重写equals方法,我确实是这样做的——但代码似乎没有被执行,它进入ArrayList.class(primitive)并在那里执行contains方法

这是因为我的类已经扩展了超类主体吗? 如果我想执行我在用户类中定义的等式,我的选项是什么

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()));
    } 
}
Principal类不重写equals方法,更重要的是,我检查相等性的属性只包含在子类User中。因此,在这里检查它是有意义的

简而言之,我有一个用户的ArrayList,我想检查某个用户是否已经存在。我在列表上调用compare,但它总是失败,这表明在我的代码中没有正确重写方法equals。
有什么建议吗?

您应该使用arrayList的contains方法


您应该使用arrayList的contains方法


问题可能来自您实例化的
列表。编译器无法知道Person的每个子类重写
是否等于
。要更正此问题,您应该向编译器承诺您将重写此方法,您可以通过将
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
    }
}

问题可能来自于实例化
列表
。编译器无法知道Person的每个子类重写
是否等于
。要更正此问题,您应该向编译器承诺您将重写此方法,您可以通过将
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
    }
}

覆盖equals并不像看上去那么明显

  • 带null的equals必须返回false
  • 具有不同类的对象的equals必须返回false,因为symetry a.equals(b)b.equals(a)
爪哇


此外,如果在哈希集合中使用对象,则它必须重写哈希代码,以便两个相等的对象必须返回相同的哈希代码,反之亦然。

重写相等并不像看上去那么明显

  • 带null的equals必须返回false
  • 具有不同类的对象的equals必须返回false,因为symetry a.equals(b)b.equals(a)
爪哇


此外,如果在哈希集合中使用对象,则它必须重写哈希代码,以便两个相等的对象必须返回相同的哈希代码,反之亦然。

您不应在超类中实现
equals()
(和
hashCode()

原因是当
equals()
返回true
hashcode()
必须返回相同的值

假设您有class
Point2D
和class
Point3D
扩展另一个

点2D是否应等于具有相同面积坐标的点3D?
如果是这样,那么point3D必须返回与“equal”point2D相同的hashcode,这意味着您不能在Hash Base集合中存储多个具有相同面积坐标的poin3d(例如:作为HashMap中的键)。

您不应该在超类中实现
equals()
(和
hashcode()

原因是当
equals()
返回true
hashcode()
必须返回相同的值

假设您有class
Point2D
和class
Point3D
扩展另一个

点2D是否应等于具有相同面积坐标的点3D?
如果是这样,则point3D必须返回与“equal”point2D相同的哈希代码,这意味着您不能在哈希基集合中存储多个具有相同面积坐标的poin3d(例如:作为哈希映射中的键)。

根据《有效Java》一书的规定。如果您已重写equals方法,则必须重写hashcode方法。 重写equals方法时的一些建议: 1.等于null返回false。 2.(此的obj实例)返回false。 3.将obj强制转换为此类,并比较obj和此类中的参数。
根据《有效Java》一书,在结尾处返回结果。如果要重写equals方法,则必须重写hashcode方法。 重写equals方法时的一些建议: 1.等于null返回false。 2.(此的obj实例)返回false。 3.将obj强制转换为此类,并比较obj和此类中的参数。
最后返回结果

您正在做的是好的。我假设您的
ArrayList
包含
Principal
对象?请在列表中实际比较的位置添加代码。1。听起来这应该是线程安全的。2.出于性能原因,最好使用更好的数据结构来容纳用户,以便更快地检索和更新。例如地图。你只需要为你的用户创建一个密钥,痛苦就会消失。或者最好是并发的-
ConcurrentHashMap
。ArrayList的类型是User,而不是Principal。您所做的很好。我假设您的
ArrayList
包含
Principal
对象?请在您实际比较列表中内容的位置添加代码。1。听起来这应该是线程安全的。2.出于性能原因,最好使用更好的数据结构来容纳用户,以便更快地检索和更新。例如地图。你只需要为你的用户创建一个密钥,痛苦就会消失。或者最好是并发的-
ConcurrentHashMap
。ArrayList的类型是User,而不是Principal。如果他不重写自己的