set继承自collection接口,其子类和子接口如下:
set的共同特性:不能添加相同的元素,通常无法记住元素添加的顺序
1.HashSet类
判断两元素相同的标准:1.equals方法返回true,2.hashCode的值相等
将元素添加进hashSet的时候,如果重写了equals方法,那么hashcode方法也应该重写,他们应该保持一致
尽量不要修改集合元素中参与计算equals和hashcode的实例变量,否则可能导致HashSet无法正确操作这些元素,比如下面这种情况
class R { int count; public R(int count) { this.count = count; } public String toString() { return "R[" + count + "]"; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj != null && obj.getClass() == R.class) { //注意,这个实现使R对象都是equals return true; } return false; } public int hashCode() { return this.count; } } public class HashSetTest2 { public static void main(String[] args) { HashSet hs = new HashSet(); hs.add(new R(5)); hs.add(new R(-3)); hs.add(new R(9)); hs.add(new R(-2)); System.out.println(hs); //[R[5], R[9], R[-3], R[-2]] Iterator it = hs.iterator(); R first = (R)it.next(); first.count = -3; System.out.println(hs); //[R[-3], R[9], R[-3], R[-2]] hs.remove(new R(-3)); System.out.println(hs);//[R[-3], R[9], R[-2]] System.out.println(hs.contains(new R(-3))); //false System.out.println(hs.contains(new R(5))); //true /*这样的结果可以看出 * 我们找到值为5的对象,将其值替换为-3之后,这个set中就有两个完全一样的元素了 * 删除值为-3的元素时,先通过hashCode找到了原来-3的元素,将其删除 * * 但是结果显示hashset中并没有-3,却有5 * 因为根据我们实现的equals方法,所有R对象都是equal的 * 但是hashcode值却是根据count的值算出来的 * 第一个元素的hashcode值是根据5算出来的,所以这个元素被hashset认为与R(5)相通,与R(-3)不同。 * * */ } }