//此类实现 Set接口,由哈希表(实际上是一个 HashMap实例)支持。它不保证 set的迭代顺序。非线程安全 JDK1.7 java.util
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable //可克隆、可序列化
{
//版本号
static final long serialVersionUID = -5024744406713321676L;
//底层是HashMap,理解HashMap,HashSet就很好懂
private transient HashMap<E,Object> map;
//底层是map,该参数与set中传入的参数构成键值对。存入map
private static final Object PRESENT = new Object();
//构造一个新的空 set,其底层 HashMap实例的默认初始容量是 16,加载因子是 0.75
public HashSet() {
map = new HashMap<>();
}
//构造一个包含指定collection中的元素的新 set。使用默认的加载因子 0.75和足以包含指定 collection中所有元素的初始容量来创建 HashMap。
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);//添加全部元素
}
//构造一个新的空 set,其底层 HashMap实例具有指定的初始容量和指定的加载因子
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
//构造一个新的空 set,其底层 HashMap实例具有指定的初始容量和默认的加载因子(0.75)。
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
//包访问权限,不对外公开,对LinkedHashSet的支持。
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
//返回对此 set中元素进行迭代的迭代器。返回元素的顺序并不是特定的
public Iterator<E> iterator() {
return map.keySet().iterator();
}
//返回此 set中的元素的数量(set的容量)。
public int size() {
return map.size();
}
//如果此 set 不包含任何元素,则返回 true
public boolean isEmpty() {
return map.isEmpty();
}
//如果此 set 包含指定元素,则返回 true
public boolean contains(Object o) {
return map.containsKey(o);
}
//如果此 set 中尚未包含指定元素,则添加指定元素
public boolean add(E e) {
//e与PRESENT构成键值对存入map中,若map中原来没有该键值对,则返回null,若有,则将值替换成PRESENT,返回原来的值。再与null比较
return map.put(e, PRESENT)==null;
}
//如果指定元素存在于此 set 中,则将其移除
public boolean remove(Object o) {
//直接移除键值对,返回的是键值对的值,再与PRESENT比较
return map.remove(o)==PRESENT;
}
//从此 set 中移除所有元素
public void clear() {
map.clear();
}
//返回此 HashSet 实例的浅表副本
public Object clone() {
try {
HashSet<E> newSet = (HashSet<E>) super.clone();
newSet.map = (HashMap<E, Object>) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
//序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject();
s.writeInt(map.capacity());
s.writeFloat(map.loadFactor());
s.writeInt(map.size());
for (E e : map.keySet())
s.writeObject(e);
}
//反序列化
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
int capacity = s.readInt();
float loadFactor = s.readFloat();
map = (((HashSet)this) instanceof LinkedHashSet ?
new LinkedHashMap<E,Object>(capacity, loadFactor) :
new HashMap<E,Object>(capacity, loadFactor));
int size = s.readInt();
for (int i=0; i<size; i++) {
E e = (E) s.readObject();
map.put(e, PRESENT);
}
}
}