我们都知道Set容器中的元素是无序不重复的,那么Set集合是怎么保证元素不重复的呢?Set是一个接口,
HashSet是Set接口的具体实现,以HashSet为例,来看一下它的具体实现。
先来看一下HashSet源码中的的几个构造器:
privatetransientHashMapmap;
privatestaticfinalObject PRESENT =newObject();//注意这个变量,待会会用到
//这个是经常使用到的构造器,可以发现无论是哪一个构造器,HashSet的底层实现都是创建了一个HashMap
publicHashSet() {
map=newHashMap();
}
publicHashSet(Collection
map=newHashMap(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
publicHashSet(intinitialCapacity,floatloadFactor) {
map=newHashMap(initialCapacity, loadFactor);
}
publicHashSet(intinitialCapacity) {
map=newHashMap(initialCapacity);
}
再来看一下HashSet的add方法的源码:
publicbooleanadd(E e) {
//PRESENT是一个虚拟值,是为了HashMap实现HashSet的一个假设的值
returnmap.put(e, PRESENT)==null;
}
当HashSet进行add操作时,其实是将要add的元素作为map的key,将PRESENT这个对象作为map的value,存入map中,并且需要注意到add方法的返回值是一个boolean。
其实到这里,我们应该能明白为什么HashSet中的元素不能重复了:
因为HashSet的底层是由HashMap实现的,而HashSet的add方法,是将元素作为map的key进行存储的,map的key是不会重复的,所以HashSet中的元素也不会重复。
接下来看个例子:
publicstaticvoidmain(String[] args) {
Set set =newHashSet();
booleanb1 = set.add(2018);
booleanb2 = set.add("Hello");
booleanb3 = set.add(2018);
System.out.println(b1);//true
System.out.println(b2);//true
System.out.println(b3);//false
}
输出一下,结果是:
true
true
false
也就是说,(结合HashSet的add方法源码)当add相同元素的时候,map.put(e, PRESENT) != null ,再来看一下一个map的例子:
输出:
null
null
11111
可以发现,当map存入相同的key的时候,返回值是上一个value,这就使得set在add相同元素的时候,map.put(e, PRESENT) != null,
导致set在执行add方法的时返回false,add失败。
领取专属 10元无门槛券
私享最新 技术干货