下面程序提供了A、B、C三个类,他们分别重写了equals(),hashcode(),两个方法中的一个或全部,通过此程序我们能大概看到HashSet判断元素相同的标准 。
package shi;
import java.util.HashSet;
//类A重写了equals()方法,使equals()方法总是返回true,但是没有重写hashCode()方法
class A {
public boolean equals(Object obj) {
return true;
}
}
//类B重写了hashCode()方法,使hashCode()方法总是返回1,但是没有重写equals()方法
class B {
public int hashCode() {
return 1;
}
}
//类C重写了两个方法,hashCode()方法总是返回2,equals()方法方法总是返回true
class C {
public boolean equals(Object obj) {
return true;
}
public int hashCode() {
return 2;
}
}
public class Practice1 {
public static void main(String[] args) {
HashSet<Object> set = new HashSet<Object>();
//向set中添加两个A对象,两个B对象,两个C对象
set.add(new A());
set.add(new A());
set.add(new B());
set.add(new B());
set.add(new C());
set.add(new C());
System.out.println(set);
}
}
程序输出结果:
[shi.A@647e05, shi.B@1, shi.B@1, shi.C@2, shi.A@10dea4e]
class C 重写了两个方法,hashCode()总是返回2,equals()总是返回true。所以HashSet将两个C对象当成了一个。即使两个对象通过equals()方法比较返回为true,但是HashSet依然当成两个对象,即使两个对象的hashCode()返回值相同,HashSet也当成两个对象。
如果两个对象通过equals()比较返回true,但是hashCode()返回值不同时,这将导致HashSet会把这两个对象保存在Hash表的不同位置,从而使两个对象都可以添加成功,这就与Set集合的规则冲突了。
注意:在重写equals()和hashSet()方法时,如果两个对象通过equals()方法比较为true时,应该使他们的hashCode()返回相同的值。