Java HashSet源码分析(JDK8)

简介

HashSet的底层是由HashMap实现的,用了HashMap的key来存储元素,value为默认的对象,因HashMap的key是不能够重复的,所以也就造成了HashSet集合元素的不可重复性。

附HashSet源码如下:
	    public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
	    {
	        static final long serialVersionUID = -5024744406713321676L;
	
		    private transient HashMap<E,Object> map;
		
		    // 空对象,放在map中的value位置
		    private static final Object PRESENT = new Object();
		
		    /**
		     *构造一个新的,空的HashSet,其底层 HashMap实例的默认初始容量是 16,加载因子是 0.75
		     */
		    public HashSet() {
		        map = new HashMap<>();
		    }
		
		    /**
		     * 构造一个包含指定 collection 中的元素的新 set,容量为传入集合长度除以默认加载因子0.75 与默认初始化容量16的最大值
		     */
		    public HashSet(Collection<? extends E> c) {
		        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
		        addAll(c);
		    }
		
		    /**
		     * 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子
		     */
		    public HashSet(int initialCapacity, float loadFactor) {
		        map = new HashMap<>(initialCapacity, loadFactor);
		    }
		
		    /**
		     *构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子0.75
		     */
		    public HashSet(int initialCapacity) {
		        map = new HashMap<>(initialCapacity);
		    }
		
		    /**
		     * Constructs a new, empty linked hash set.  (This package private
		     * constructor is only used by LinkedHashSet.) The backing
		     * HashMap instance is a LinkedHashMap with the specified initial
		     * capacity and the specified load factor.
		     *
		     * @param      initialCapacity   the initial capacity of the hash map
		     * @param      loadFactor        the load factor of the hash map
		     * @param      dummy             ignored (distinguishes this
		     *             constructor from other int, float constructor.)
		     * @throws     IllegalArgumentException if the initial capacity is less
		     *             than zero, or if the load factor is nonpositive
		     */
		    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
		        map = new LinkedHashMap<>(initialCapacity, loadFactor);
		    }
		
		    /**
		     * 返回对此 set 中元素进行迭代的迭代器
		     */
		    public Iterator<E> iterator() {
		        return map.keySet().iterator();
		    }
		
		    /**
		     * 获取数组个数,实际上是获取底层map中数据的个数
		     */
		    public int size() {
		        return map.size();
		    }
		
		    /**
		     * 判断是否为空,实际上是判断map中的size是否等于0
		     */
		    public boolean isEmpty() {
		        return map.isEmpty();
		    }
		
		    /**
		     * 是都包含某元素,实际上是判断是否包含key,因为set只有单值,所map中其实只用到了key,map为空对象
		     */
		    public boolean contains(Object o) {
		        return map.containsKey(o);
		    }
		
		    /**
		     *调用map的put方法,其中value值为静态的Object对象
		     */
		    public boolean add(E e) {
		        return map.put(e, PRESENT)==null;
		    }
		
		    /**
		     * 删除元素调用的是map的remove函数
		     */
		    public boolean remove(Object o) {
		        return map.remove(o)==PRESENT;
		    }
		
		    /**
		     * 清空集合,调用的是map的clear()
		     */
		    public void clear() {
		        map.clear();
		    }
		
		    /**
		     * 返回此 HashSet 实例的浅表副本
		     */
		    @SuppressWarnings("unchecked")
		    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(e);
		        }
		    }

	}
	
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Starry-Leo

帮到了您,有闲钱,再打赏哦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值