HashSet源码分析

今天来分析HashSet源码

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable

打开HashSet源码发现,HashSet是继承自AbstractSet,实现了Clonable和Serializable类,而我们知道Set接口是继承自Collection的。

HashSet内部属性:


static final long serialVersionUID = -5024744406713321676L;
//通过HashMap保存对象
private transient HashMap<E,Object> map;
//定义一个虚拟的Object PRESENT是向map中插入key-value对应的value
//该map的key就是HashSet要存放的数据,而HashMap不允许key重复,所以HashSet不允许值重复
private static final Object PRESENT = new Object();

我们发现,HashSet内部原来是基于HashMap实现的,因此我们有了信心阅读下去

HashSet主要方法:(我们的顺序是根据源码行的顺序阅读的)

HashSet的无参数构造函数:

public HashSet() {
        map = new HashMap<>();
    }

默认的HashSet构造函数内部调用了默认的HashMap构造函数,实际只是实例化了hashMap对象,而我们知道默认的HashMap构造函数默认的大小是16,默认的加载因子是0.75

HashSet一个参数构造函数:

public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

传入指定的初始化大小参数,同样把初始化大小传给HashMap,实现初始化。

HashSet两个参数构造函数:

public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

Hash添加元素add(E e)方法:

 //添加一个元素,如果该元素已经存在,则返回true,如果不存在,则返回false
public boolean add(E e) {    
        //往map中添加元素,返回null,说明是第一个往map中添加该key
        return map.put(e, PRESENT)==null;
        //把PRESENT作为value,所以map中的所有key对应的value都相等
    }
  • 往hashset中添加元素,实际是往map成员变量里面添加对应的key和value
  • map中的key实际就是要添加的元素,value是一个固定对象PRESENT
  • 当第一次往map中添加key时,添加成功返回null,所以当第一次往HashSet中添加元素时,会返回true
  • 由于HashMap中的key不能重复,所以HashSet不能存储重复元素
  • 因为HashMap存储元素是Hash散列存储,所以HashSet中的元素也是无序的

删除元素方法remove(Object o)

 //删除指定的元素,删除成功返回true
public boolean remove(Object o) {
        //实际是删除map中的一个对象
        return map.remove(o)==PRESENT;
    }
  • 当hashset删除一个元素时,实际是操作map删除对应的元素
  • 当删除map中一个不存在的对象时,会返回null,所以这里当返回PRESENT时,说明之前HashSet往map中添加过对应的元素,因此,当remove(o)返回true时,说明之前已经存在该元素,并且成功删除,当返回false时,说明之前并没有添加过该对象。

hashet也没有提供get方法,可以通过Iterator迭代器获取数据

public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

总结:

  1. HashSet内部使用HashMap的key来存储元素,来保证元素不重复
  2. HashSet是无序的,因为HashMap是散列存储,所以无序
  3. HashSet中允许有一个null元素,以为HashMap允许key为null
  4. HashSet非线程安全
  5. HashSet没有get方法,获取方法是通过HashMap的迭代器实现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值