Set是一个不包含重复元素的 Collection。(似乎我在废话)
让我们来看一段代码:
int a=1,b=2,c=3,d=4,e=5,f=6;
Set<Collection<Integer>> setClear = new HashSet<Collection<Integer>>();//定义一个用于测试的Set
ArrayList<Integer> setClearInner = new ArrayList<Integer>();//定义上述的用于放进Set中的元素
setClearInner.add(a);
setClearInner.add(b);
setClearInner.add(c);
setClear.add(setClearInner);
setClearInner.clear();//清除setClearInner内的元素
setClearInner.add(d);
setClearInner.add(e);
setClearInner.add(f);
setClear.add(setClearInner);
System.out.println("setClear ========" + setClear.toString());//输出setClear内的元素
Iterator<Collection<Integer>> it = setClear.iterator();
Collection<Integer> temp1 = it.next();
Collection<Integer> temp2 = it.next();
/*比较setClear内的两个元素,比输出它们各自的hash码*/
System.out.println("equals ========" + temp1.equals(temp2));
System.out.println("temp1.hashCode() ========" + temp1.hashCode());
System.out.println("temp2.hashCode() ========" + temp2.hashCode());
猜一下什么结果。false?看一下:
setClear ========[[4, 5, 6], [4, 5, 6]]
equals ========true
temp1.hashCode() ========33796
temp2.hashCode() ========33796
没有看错,的确在Set里添加了同一元素!
在JDK API对Set的描述有这么一句话:
如果将可变对象用作 set 元素,那么必须极其小心。如果对象是 set 中某个元素,以一种影响 equals 比较的方式改变对象的值,那么 set 的行为就是不确定的。
正是这种不确定性,使我们往Set里添加了同一元素。
再看一段代码:
int a=1,b=2,c=3;
Set<Integer> setClear = new HashSet<Integer>();
setClear.add(a);
setClear.add(b);
setClear.add(c);
System.out.println("first:setClear ========" + setClear.toString());
a=2;
b=3;
c=4;
setClear.add(a);
setClear.add(b);
setClear.add(c);
System.out.println("second:setClear ========" + setClear.toString());
输出结果为:
first:setClear ========[1, 2, 3]
second:setClear ========[1, 2, 3, 4]
Set只是添加了它原本没有包含的元素4。
说明Set的不确定性只用在对象上,不适合于基本数据类型。换一种说法,往Set里添加基本数据类型,添加的是基本数据类型的值;如果添加的是对象,则添加的时对象的一个引用,对象属性的改变,引起了Set的不确定性。
这个问题是在一个技术群里的一个人问起的,我和他讨论解决之后,决定把它发上来大家就流一下。