浅析HashSet源码

对于 HashSet 而言,它是基于 HashMap 实现的,底层采用 HashMap 来保存元素,所以如果对 HashMap 比较熟悉了,那么学习 HashSet 也是很轻松的。HashSet是一个存放无序数据和无重复数据的集合。

构造方法
// HashSet底层是通过HashMap来实现的,所以具有HashMap的大部分特性
private transient HashMap<E,Object> map;

// 无参构造方法
public HashSet() {
     
    map = new HashMap<>();
}

// 有参构造方法-1
public HashSet(int initialCapacity) {
     
    map = new HashMap<>(initialCapacity);
}

// 有参构造方法-2
public HashSet(int initialCapacity, float loadFactor) {
     
    map = new HashMap<>(initialCapacity, loadFactor);
}

// 有参构造方法-3
public HashSet(Collection<? extends E> c) {
     
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

// 有参构造方法-4,dummy其实无实际意义只是为了区分的重载方法,用了LinkedHashMap
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
     
	map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

我们可以看到HashSet的底层是HashMap来实现的。构造方法都是调用的HashMap的构造方法,之前在HashMap的源码分析中详细介绍了这几个构造方法,这里就不再详细介绍了。

HashSet是如何实现元素不重复的

HashSet的add方法,通过源码可以看到其实是调用了map的put方法,map的key是新增的元素,value是一个固定的值,因此HashSet的所有key的value都是一样的。

// 固定值
private static final Object PRESENT = new Object();

public boolean add(E e) {
     
	return map.put(e, PRESENT)==null;
}

看到这里熟悉HashMap的小伙伴已经能明白为什么HashSet能够做到存放不重复的元素了。其实原理很简单,看一看HashMap的put方法就全都明白了。因为:HashMap在存放数据的时候,首先会对key进行过hash,然后比较key是否重复了,如果重复就会直接替换value的值,对于HashSet而言新旧value都是PRESENT。

简单一句话来说:HashMap中的key不允许重复,所以HashSet就不会存储重复元素

你可能感兴趣的:(Java)