java数据结构源码解读——HashSet

HashSet在我们编程中是最长使用的一种Set,它能够以常数时间插入/删除/查找。正因为其强大的性能,python里的set也是以它的原理为实现的。我们都知道python向来崇尚“简单好于复杂 ————python之禅”,连python都认可的数据结构当然要看看。

经过多场面试,可能面试经验总是说:HashSet是以HashMap来实现的。那么,具体是怎样实现的呢?

接下来就探索一下它的底层原理——我说它才200多行你敢信?

首先,观察它的字段:

static final long serialVersionUID = -5024744406713321676L;//序列化时校验ID
private transient HashMap<E,Object> map;//HashMap结构
private static final Object PRESENT = new Object();//一个占位对象。

聪明的小伙伴已经猜到了——HashMap的key-value中的value都将以PRESENT代替,这样不占用空间,并且操作方便。

构造器:

    public HashSet() {
        map = new HashMap<>();//默认构造一个HashMap
    }
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);//调用HashMap,并且集合的元素保持3/4的装填率
    }
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);//自定义
    }
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
        //由dummy参数表示是否构造有序hashset
    }

几个操作方法:

public boolean contains(Object o) {
        return map.containsKey(o);//搜索
    }
 public boolean add(E e) {
        return map.put(e, PRESENT)==null;//插入(以PRESENT占位)
    }
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;//删除
    }

通过查看这几个方法,我们可以得出几个设计哲学的发现:

1、因为所有的键值对的值都引用的是一个占位对象,所以使用了“单例模式”。

2、HashSet的方法远远不如HashMap的丰富,所以使用了“代理模式”,通过调用HashMap的方法达到目的,因为很多方法被隐藏了起来,我们称这种方法为接口窄化。

 

那么分析到此结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值