【发布时间】:2019-09-24 08:06:59
【问题描述】:
我正在查看一些代码,发现一个程序在其中扩展了 HashSet 集合类。他们创建了自定义员工对象并插入到 Set 中,而没有实现 Comparable 或 Comparator。他们实现了识别重复员工对象的逻辑,因此如果对象已经存在,他们可以执行更新操作,如果对象不存在,他们可以执行插入操作。我试图了解 set 如何在不实现 Comparable 或 Comparator 接口的情况下识别重复对象。
我已经尝试过同样的方法,也尝试过重写 Hashcode 和 equals 方法来了解 Set 如何比较对象。我发现的一件事是,当我添加相同的对象来设置它生成相同的哈希码时。但它没有调用我已经覆盖的equals方法。
class Employee {
int id;
String name;
Employee(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
System.out.println("HashCode : " + super.hashCode());
return super.hashCode();
}
@Override
public boolean equals(Object o) {
System.out.println("Equals : " + super.equals(o));
return super.equals(o);
}
}
class LimitedHashSet extends HashSet<Employee> {
public boolean add(Employee e) {
if(!super.add(e)){
return false;
}
return true;
}
}
public class ExtendingHashSet {
public static void main (String[] args) {
Employee e0 = new Employee(1,"A");
Employee e1 = new Employee(2,"B");
LimitedHashSet obj = new LimitedHashSet();
System.out.println("Element added ? " + obj.add(e0) + "\n");
System.out.println("Element added ? " + obj.add(e1) + "\n");
System.out.println("Element added ? " + obj.add(e0) + "\n");
}
}
Hashcode用于计算bucket,equals方法识别其是否相等。那么它是如何在这里工作的。请检查下面的输出。
输出:
哈希码:914424520 添加元素 ?真的
哈希码:110718392 添加元素 ?真的
哈希码:914424520 添加元素 ?假的
【问题讨论】:
-
@AndyTurner:代码在最后一行调用
obj.add(e0),而不是obj.add(e3)。 -
@Aks1316 你的意思是第二次添加
e3而不是e0? -
另外:您认为在
LimitedHashSet中覆盖add有什么作用?看起来就相当于只调用return super.add(e);。 -
@AndyTurner 不再添加 e0。如果我添加 e3 它将返回 true 并将 e3 添加到 set 没有任何问题。但是,如果我尝试再次添加 e0,则它不会将其添加到集合中并为我提供结果 false,如输出所示。
-
@AndrewS 这在几个层面上具有误导性。关键是
Employee,而不是hashCode。给定上面的实现,具有相同属性值的 Employee 对象当前具有不同的哈希码。
标签: java arraylist collections