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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值