我正在尝试在两个不同位置之间同步用户,因此我将现有用户保留在列表中,然后以设定的时间间隔进行比较,以查看是否应该添加(新)用户或只是更新用户。
我有一个用户类,它是校长的子类。
但是我在列表中的比较不起作用;我用谷歌搜索了一下,发现你必须重写 equals 方法,我确实这样做了 - 但该代码似乎没有被执行,它进入 ArrayList.class (原始)并在那里执行 contains 方法。
这是因为我的类已经扩展了超类校长吗? 如果我想执行我在 User 类中定义的 equals,我有什么选择?
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 中。因此在这里检查是有意义的。
简而言之,我有一个用户数组列表,我想检查某个用户是否已经存在。我在列表上调用比较,但它总是失败,这表明我的代码中没有正确覆盖方法 equals。 有什么建议吗?
您不应该在超类中实现
equals()
(和 hashcode()
)。
原因是当
equals()
返回 true hashcode()
必须返回 same 值
想象你有班级
Point2D
和班级 Point3D
延伸另一个。
point2D是否应该等于具有相同区域坐标的point3D? 如果是这样,那么 point3D 必须返回与“相等”point2D 相同的哈希码,这意味着您不能在哈希基集合中存储多个具有相同区域坐标的 point3d (例如:作为哈希映射)。
覆盖 equals 并不像看起来那么明显
java
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass()!=getClass()) {
return false;
}
return Objects.equals(this.getAlias(),((User) obj).getAlias())
&& Objects.equals(this.getEmailAddress(),((User) obj).getEmailAddress())
&& Objects.equals(this.getCellNumber(),((User) obj).getCellNumber()));
}
此外,如果在哈希集合中使用对象,则它必须覆盖 hashCode,以便两个相等的对象必须返回相同的 hashCode,反之则不然。
问题可能来自于您实例化
List<Person>
。编译器无法知道 Person 的每个子类是否都重写了equals
。要纠正这个问题,您应该承诺您的编译器将重写此方法,您可以通过将您的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
}
}
根据Effective Java一书,如果你重写了equals方法,那么你必须重写hashcode方法。 重写 equals 方法时的一些建议: 1. 等于 null 返回 false。 2. !(obj instanceof this) 返回 false。 3.将obj强制转换为此类,并比较obj和此类中的参数。 最后返回结果
您应该使用 arrayList 的 contains 方法
https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html