HashSet 是一个集合类,也可理解为一个容器。用来盛装各种元素,无顺序且不可重复。
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据该 hashCode 值来决定该对象在 HashSet 中的存储位置。
如果有两个元素通过 equals 方法比较返回 true,但是他们的 hashCode() 方法返回值不相等,HashSet 会将他们存储在不同位置,也就可以添加成功。
如果向 HashSet 中添加一个可变对象后,并且后面程序修改了该可变对象的属性,可能导致它与集合中其他元素相同 (即两个对象通过 equals 方法比较返回 true,两个对象的 hashCode 值也相等),这就有可能导致 HashSet 中包含两个相同的对象。
如下代码所示:
public class TestHashSet {
public static void main(String[] args) {
Collection c1 = new HashSet();
c1.add(new R(-3));
c1.add(new R(5));
c1.add(new R(8));
c1.add(new R(3));
//false
System.out.println(c1.add(new R(-3)));
//[R(count属性:-3), R(count属性:3), R(count属性:5), R(count属性:8)]
System.out.println(c1);
Iterator it = c1.iterator();
R first = (R)it.next();
//first.count = 3,但是first.hashCode = -3
first.count = 3;
//[R(count属性:3), R(count属性:3), R(count属性:5), R(count属性:8)]
System.out.println(c1);
//删除和new R(3)的hashCode一样,且equals(new R(3))为true的元素
c1.remove(new R(3));
//[R(count属性:3), R(count属性:5), R(count属性:8)]
System.out.println(c1);
//false
System.out.println("c1是否包含count为-9的元素?" + c1.contains(new R(3)));
//false
System.out.println("c1是否包含count为5的元素?" + c1.contains(new R(-3)));
}
}
class R {
int count;
//构造函数
public R(int count) {
this.count = count;
}
//重写toString()方法
@Override
public String toString() {
return "R(count属性:" + count + ")";
}
//重写equals()方法,
@Override
public boolean equals(Object obj) {
if (obj instanceof R) {
R r = (R)obj;
if (r.count == this.count) {
return true;
}
}
return false;
}
//重写hashCode()方法
@Override
public int hashCode() {
return this.count;
}
}
输出结果如下: