疯狂java讲义精粹_《疯狂Java讲义精粹》读书笔记13 ------ Set集合(二)

上面的输出结果可能有点让人觉得意外,从输出的结果可知输出的内容已经重复了(有两个-3),但是因为HashSet把他们添加到了不同的地方,所以HashSet完全可以容纳两个相同的元素。

但是当我们试图删除count为-3的R对象的时候,HsahSet会计算出该对象的hsahCode值,从而找出该对象在集合中保存的位置,然后把此处的对象与count为-3的R对象通过equals()方法进行比较,如果相等就删除该对象-----HashSet只有第三个元素才满足该条件(第一个元素实际上是存的count值为5的R 对象对应的位置,所以第三个元素会被删除)。

因此在修改HashSet集合中的对象时,应该考虑到,修改有可能导致该对象与集合中的其他对象相等,从而导致HashSet无法准确访问该对象。

同样的情况也会发生在TreeSet中,如果向TreeSet中添加一个可变对象后,后面的程序修改了改可变对象的成员变量,这将导致与其他对象的大小顺序发生改变,但是TreeSet不会再次调整他们的顺序,甚至可能导致这两个对象通过compareTo(Object obj)方法比较返回0.下

================《疯狂Java讲义精粹》读书笔记13 ------  Set集合(二)==============

在上一篇笔记中提出了这样一个问题:修改Set中对象的成员变量之后可能与集合中的其他元素相等,这不就与Set集合的规则矛盾了吗?

先考虑HashSet的情况:

import java.util.HashSet;

import java.util.Iterator;classR{intcount;public R(intcount){this.count =count;

}//重写toString()方法

publicString toString(){return "R[count:" + count + "]";

}//重写equals()方法

publicboolean equals(Object obj){if(this ==obj){return true;

}if(obj != null && obj.getClass() == R.class){

R r=(R)obj;if(r.count == this.count){return true;

}

}return false;

}//重写hashCode()方法

public inthashCode(){return this.count;

}

}public classTestHashSet {public static voidmain(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);

Iterator it =hs.iterator();

R first=(R)it.next();//为第一个元素的count实例变量赋值

first.count = -3;//再次输出HashSet集合,集合内有重复的元素

System.out.println(hs);//删除count为-3的元素,只被删除了一个元素

hs.remove(new R(-3));

System.out.println(hs);//还是否包含count值为-3的元素//很奇怪的是,会输出false

System.out.println("hs中是否还存在count = -3的元素:" + hs.contains(new R(-3)));//count值为5 的元素不存在了

System.out.println("hs中是否包含count值为5 的元素:" + hs.contains(new R(5)));

}

}

输出的结果是:

[R[count:5], R[count:9], R[count:-3], R[count:-2]]

[R[count:-3], R[count:9], R[count:-3], R[count:-2]]

[R[count:-3], R[count:9], R[count:-2]]

hs中是否还存在count= -3的元素:falsehs中是否包含count值为5 的元素:false

上面的输出结果可能有点让人觉得意外,从输出的结果可知输出的内容已经重复了(有两个-3),但是因为HashSet把他们添加到了不同的地方,所以HashSet完全可以容纳两个相同的元素。

但是当我们试图删除count为-3的R对象的时候,HsahSet会计算出该对象的hsahCode值,从而找出该对象在集合中保存的位置,然后把此处的对象与count为-3的R对象通过equals()方法进行比较,如果相等就删除该对象-----HashSet只有第三个元素才满足该条件(第一个元素实际上是存的count值为5的R 对象对应的位置,所以第三个元素会被删除)。

因此在修改HashSet集合中的对象时,应该考虑到,修改有可能导致该对象与集合中的其他对象相等,从而导致HashSet无法准确访问该对象。

同样的情况也会发生在TreeSet中,如果向TreeSet中添加一个可变对象后,后面的程序修改了改可变对象的成员变量,这将导致与其他对象的大小顺序发生改变,但是TreeSet不会再次调整他们的顺序,甚至可能导致这两个对象通过compareTo(Object obj)方法比较返回0.下面的程序演示了这种情况:

importjava.util.TreeSet;class T implementsComparable{intcount;public T(intcount) {this.count =count;

}publicString toString(){return "T[count:" + count + "]";

}//重写equals方法,根据count来判断是否相等

public booleanequals(Object obj) {if(this ==obj){return true;

}if (obj != null && obj.getClass() == T.class) {

T t=(T)obj;if(t.count == this.count){return true;

}

}return false;

}//重写compareTo()方法,根据count来比较大小

@Overridepublic intcompareTo(Object obj){

T t=(T)obj;return count>t.count?1:

count< t.count?-1:0;

}

}public classTreeSetTest {public static voidmain(String[] args) {

TreeSet ts = new TreeSet();

ts.add(new T(5));

ts.add(new T(-3));

ts.add(new T(9));

ts.add(new T(-2));

System.out.println(ts);

T firs=ts.first();

firs.count= 20;//修改后没有排序

System.out.println(ts);

T last=ts.last();

last.count= -2;//将会看到集合里的元素处于无序状态,且有重复的元素

System.out.println(ts);//删除count=-2的T对象,将会删除失败

System.out.println(ts.remove(new T(-2)));

System.out.println(ts);//查询是否有count=20的T对象

System.out.println("是否存在count=20的T对象:" + ts.contains(new T(20)));

}

}

输出结果:

[T[count:-3], T[count:-2], T[count:5], T[count:9]]

[T[count:20], T[count:-2], T[count:5], T[count:9]]

[T[count:20], T[count:-2], T[count:5], T[count:-2]]false[T[count:20], T[count:-2], T[count:5], T[count:-2]]

是否存在count=20的T对象:false

与HashSet类似如果修改了TreeSet中的可变对象,会很容易出错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值