下面程序提供了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()返回相同的值。