package java.util;
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
//这就是底层的使用HashMap来保存数据的原因
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
/**
* 默认的无参构造器,实际底层会初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75。
*/
public HashSet() {
map = new HashMap<E,Object>();
}
/**
* 有参构造器,第一个参数是默认容量,第二个为默认的,Math.max的作用是选出两个参数的最大值,第一个参数为默认转载因子算出来的当前最大容量,
* 相当于这个c的size为阈值,第二个为默认的16大小,
* 足以使用方法addAll方法把c转入HashMap
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
/**
* 自己指定容量和,装载因子
*/
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<E,Object>(initialCapacity, loadFactor);
}
/**
* 自己指定容量,装载因子默认
*/
public HashSet(int initialCapacity) {
map = new HashMap<E,Object>(initialCapacity);
}
/**
* 以指定的initialCapacity和loadFactor构造一个新的空链接哈希集合。
* 此构造函数为包访问权限,不对外公开,实际只是是对LinkedHashSet的支持。
* 实际底层会以指定的参数构造一个空LinkedHashMap实例来实现。
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}
/**
* 返回HashMap里面的一个内部类keySet,在c集合的元素就保存在HashMap上的key中,它返回元素的顺序随机
*/
public Iterator<E> iterator() {
return map.keySet().iterator();
}
/**
* 放回的底层HashMap键值对Entry的个数,也就是HashSet的尺寸
*/
public int size() {
return map.size();
}
/**
* 用到HashMap的isEmpty()方法,略
*/
public boolean isEmpty() {
return map.isEmpty();
}
/**
* 用到HashMap的containsKey(o)方法,略
*/
public boolean contains(Object o) {
return map.containsKey(o);
}
/**
* PRESENT是HashSet先前定义的一个Object,引文HashMap的put方法是放入键值对,
* 由于HashMap的put()方法添加key-value对时,当新放入HashMap的Entry中key会事先
* 与集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true),
* 新添加的Entry的value(PRESENT)会将覆盖原来Entry的value,但key不会有任何改变,
* 因此如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中,
* 原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性。
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
/**
* 使用HashMap的remove方法,略
*/
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
/**
* 略
*/
public void clear() {
map.clear();
}
/**
* 调用HashMap的clone副本,使用原来的值,
*
*/
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 (Iterator i=map.keySet().iterator(); i.hasNext(); )
s.writeObject(i.next());
}
/**
* 不懂
*/
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);
}
}
}
一个学生对HashSet源码的注释学习
最新推荐文章于 2024-09-15 19:46:31 发布