Java集合框架系列之——HashSet

HashSet

前言

首先我们来看到HashSet的类图结构,如下所示:

可以看到HashSet继承于AbstractSet,且其内部其实使用的是HashMap来存储数据。数据存储在HashMap中的key中,value是一个默认值,所以其内部的方法大部分都是HashMap的方法,且HashSet存储的值是不能重复的。

源码

从源码中我们可以很清楚的看到HashSet是如何使用HashMap存储数据的,并且它实现了Set接口中所有的方法,在这里我们只对一些常用的方法进行解析,收首先它的构造方法如下所示:

 private transient HashMap<E,Object> map;

    // PRESENT则是用来虚拟一个假的value,作为Map的值
    private static final Object PRESENT = new Object();

    /**
     * 使用HashMap构造一个空的HashSet对象,初始容量为16,负载因子为0.75,相当于初始化一个空的HashMap对象
     */
    public HashSet() {
        map = new HashMap<>();
    }

    /**
     * 构造包含指定集合中的元素的新集合
     * 创建一个HashMap对象,默认负载因子是0.75,容量大小取指定集合和默认初始大小16中最大值
     */
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

    /**
     * 根据指定容量大小和指定的负载因子,基于HashMap创建一个空的HashSet
     */
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

    /**
     * 根据指定初始容量大小,基于HashMap创建一个空的HashSet,默认负载因子为0.75
     */
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

其他常用方法如下所示:

    /**
     * 返回集合中元素数量,注意map.size(),实际是map中元素的数量
     */
    public int size() {
        return map.size();
    }
    /**
     * 判断集合中是否抱恨指定的元素,实际判断map中是否包含指定元素作为key的对象
     */
    public boolean contains(Object o) {
        return map.containsKey(o);
    }

    /**
     *将指定元素添加到集合中,该元素作为map中的key,PRESENT作为值
     */
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

    /**
     * 从集合中移除指定的元素
     */
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

HashSet元素不重复的原理

由源码中的add方法可知,HashSet往集合中添加元素,其实就是作为HashMap的key存储,由于HashMap的put方法在添加key-value的时候,当新放入HashMap的Entry中key与集合中原有Entry有重复的话(hashCode()返回值相等且equals()方法也返回true),新添加的Entry的value值会被覆盖,但是key是不是有所变动的,所以如果向HashSet中放入重复的元素,原来的元素也不会有任何的变化,这也就满足了Set中元素不重复的特性。

如果添加的元素在HashSet中不存在,那么返回true,如果添加的元素已经存在,返回false。其原因在于HashMap中的put方法,如果添加key不重复的键值对的时候,会返回null。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值