我正在看一些代码,找到了一个扩展了HashSet类集合的程序。他们创建了自定义员工对象并插入到Set中,而没有实现Comparable或Comparator。他们实施了逻辑来识别重复的员工对象,因此如果对象已经存在,则可以执行更新操作(如果不存在对象),则可以执行插入操作。我试图了解set如何在没有实现Comparable或Comparator接口的情况下识别重复的对象。
我尝试了相同的方法,还尝试重写Hashcode和equals方法,以了解如何设置比较对象。我发现一件事是,当我添加相同的对象以设置其生成相同的哈希码时。但是它没有调用我已经覆盖的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");
}
}
哈希码用于计算存储桶,equals方法标识其是否等于。那么它在这里如何工作。请检查下面的输出。
输出:
哈希码:914424520 添加元素?是
哈希码:110718392 添加元素?是
哈希码:914424520 添加元素?错误
答案 0 :(得分:4)
根本上,没有魔术。
HashSet
和所有基于JDK哈希的集合盲目地使用hashCode
和equals
定义的实现来确定对象是否相同。他们只是调用hashCode
和equals
方法,但是这些方法都起作用,这就是哈希集合的用途。
使用hashCode
方法的部分要点-首先是基于散列的数据结构的要点-是使不太可能基于哈希的集合甚至不得不费心调用equals
方法来检查两个对象是否相同。如果哈希值不相同,则对象肯定不相等。因此,它会将调用您需要重写的equals
方法,但是在您的代码中,它无需费心调用equals
。此外,它还会在调用equals
方法之前检查引用的相等性,因为如果两个对象是==
,那么它们肯定是彼此.equals
。
当前,您两次添加e0
。通过引用相等,e0 == e0
,所以它不会打扰.equals
-它只是找到匹配的条目,检查它们是否等于引用,并保留现有条目而无需添加新元素。顺便说一下,这是正确的行为,因为e0
是其自身的副本。