Set是一个常见接口,用来保存不同的元素。常用的实现了Set接口的类有HashSet,TreeSet。一个底层基于HashMap实现,另一个基于TreeMap实现,理解了上述两个Map之后分析Set源码就比较简单了。
HashSet源码分析
hashset 基于HashMap实现,把传入的值作为HashMap的key,由于底层HashMap的key是不可能重复的,因此HashSet也是不会重复的,即其中包含的所有元素都不重复,只保存一份。
重要参数及构造函数
private transient HashMap<E,Object> map;//底层是一个HashMap
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
/**
* 构造一个默认的HashSet,底层的hashMap容量是16,负载因子是0.75
*/
public HashSet() {
map = new HashMap<>();
}
/**
* 构造一个指定集合的HashSet,底层的HashMap容量是集合大小/0.75和默认容量的最大值
* 然后把集合的值放入HashSet中
* @param c the collection whose elements are to be placed into this set
* @throws NullPointerException if the specified collection is null
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
/**
* 使用所给的容量和构造因子构造一个HashMap
*
* @param initialCapacity the initial capacity of the hash map
* @param loadFactor the load factor of the hash map
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive
*/
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
/**
* 只包含容量,负载因子默认0.75
*
* @param initialCapacity the initial capacity of the hash table
* @throws IllegalArgumentException if the initial capacity is less
* than zero