JDK源码解析之HashSet

一、简介

HashSet是基于HashMap实现的Java集合,它可以保证存储的元素不重复

  • HashSet的底层就是通过HashMapkey来保存元素,从而保证存储的元素不重复
  • 如果对HashMap熟悉的话,HashSet基本也就掌握了,它的底层源码相对简单多了。如果对HashMap不熟悉,可以参考我之前的文章:JDK源码解析之HashMap
  • 基于JDK1.8版本

二、类图

实现了三个接口

  • 实现 java.util.Set接口
  • 实现 java.io.Serializable 接口。
  • 实现 java.lang.Cloneable接口。

继承了一个抽象类

  • 继承 java.util.AbstractSet 抽象类。

三、属性和构造方法

1. 属性

//序列化版本号
static final long serialVersionUID = -5024744406713321676L;

//存放元素(存放在key上)
private transient HashMap<E,Object> map;

//因为HashSet不存放value,所以这里定义一个统一的对象作为value
private static final Object PRESENT = new Object();

属性主要是一个HashMapkey存放元素,value为统一的对象(可忽略)。

2. 构造方法

HashSet一共有5个构造方法

  • HashSet()

    public HashSet() {
        //直接new一个HashMap
        map = new HashMap<>();
    }
    
  • HashSet(int initialCapacity)

    public HashSet(int initialCapacity) {
        //指定HashMap的初始容量
        map = new HashMap<>(initialCapacity);
    }
    
  • HashSet(int initialCapacity, float loadFactor)

    public HashSet(int initialCapacity, float loadFactor) {
        //指定HashMap的初始容量和加载因子
        map = new HashMap<>(initialCapacity, loadFactor);
    }
    
  • HashSet(int initialCapacity, float loadFactor, boolean dummy)

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
    

    该构造方法的访问权限仅仅为包权限不对外开放,即根据指定的初始化容量和负载因子构造一个LinkedHashMapdummy只是一个标识。该构造方法主要是为了支持LinkedHashSet,本文暂不研究它。

  • HashSet(Collection<? extends E> c)

    public HashSet(Collection<? extends E> c) {
        //Math.max((int) (c.size()/.75f) + 1, 16)计算最小所需容量,最小为16,避免扩容
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        //批量添加元素
        addAll(c);
    }
    

四、添加操作

  • add(E e)

    添加单个元素,返回添加是否成功

    public boolean add(E e) {
        //直接调用HashMap的添加方法,默认value为PRESENT
        return map.put(e, PRESENT)==null;
    }
    
  • addAll(Collection<? extends E> c)

    批量添加元素,返回是否有元素添加成功

    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }
    

    addAll方法在AbstractCollection中,里面调用HashSet重写的add方法。

五、移除操作

移除指定元素,返回是否移除成功

public boolean remove(Object o) {
    //直接调用HashMap的remove方法
    return map.remove(o)==PRESENT;
}

六、查找操作

判断指定元素是否存在

public boolean contains(Object o) {
    //直接调用HashMap的containsKey方法
    return map.containsKey(o);
}

七、其他操作

  • clear()

    清空集合

    public void clear() {
        //因为HashSet底层就是HashMap,所以清空HashSet就是清空HashMap
        map.clear();
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值