一个学生对HashSet源码的注释学习

来源:互联网 发布:mac版office威锋 编辑:程序博客网 时间:2024/05/16 18:58
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);        }    }}

0 0