HashSet源码分析
一、HashSet简介
HashSet存储的是无序、不重复的对象。每组数据都没有索引,需要通过索引来进行操作的方法都没有,所以也不能使用普通for循环来进行遍历。存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取的。
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
HashSet继承AbstractSet类,实现Set、Cloneable、Serializable接口。
有四种构造函数
//默认构造函数,创建一个大小为16的容器,加载因子为0.75
public HashSet() {
map = new HashMap<>();
}
// 带集合的构造函数
public HashSet(Collection<? extends E> c) {
// 因为从HashMap的效率(时间成本和空间成本)考虑,HashMap的加载因子是0.75。
// 当HashMap的“阈值”(阈值=HashMap总的大小*加载因子) < “HashMap实际大小”时,就要将HashMap的容量翻倍。
// 所以,(c.size()/.75f) + 1 计算出来的正好是总的空间大小。
map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
// 将集合(c)中的元素都添加到HashSet中
addAll(c);
}
// 指定HashSet初始容量和加载因子的构造函数
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<E,Object>(initialCapacity, loadFactor);
}
// 指定HashSet初始容量的构造函数
public HashSet(int initialCapacity) {
map = new HashMap<E,Object>(initialCapacity);
}
二、主要方法
2.1 add()方法
底层利用了HashMap键进行了元素的添加。
HashMap的put()方法中,该方法的返回值是对应HashMap中键值对中的值,
//如果当前列表中没有e则将e加进去
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
2.2 clear()方法
从set中移除所有元素。调用HashMap的clear方法清空所有元素。
public void clear() {
map.clear();
}
2.3 remove()方法
如果指定元素存在于此set中,则将其移除。如果此set已包含该元素,则返回true。调用HashMap的remove方法删除指定Entry。
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
public V remove(Object key) {
Node<K,V> e;
return (e = removeNode(hash(key), key, null, false, true)) == null ?
null : e.value;
}
2.4 contains()方法
底层实际调用HashMap的contains Key,判断是否包含指定key
public boolean contains(Object o) {
return map.containsKey(o);
}
2.5 iterator()方法
返回对此set中元素进行迭代的迭代器。返回元素的顺序并不是特定的。调用底层HashMap的keySet来返回所有的key。
public Iterator<E> iterator() {
return map.keySet().iterator();
}

浙公网安备 33010602011771号