java.util.HashSet源码解析

1、什么是HashSet

HashSet 是一个由 HashMap 实现的集合。元素无序且不能重复。
在这里插入图片描述
和前面介绍的大多数集合一样,HashSet 也实现了 Cloneable 接口和 Serializable 接口,分别用来支持克隆以及支持序列化。还实现了 Set 接口,该接口定义了 Set 集合类型的一套规范。

2、字段属性

 //HashSet集合中的内容是通过 HashMap 数据结构来存储的
 private transient HashMap<E,Object> map;
 //向HashSet中添加数据,数据在上面的 map 结构是作为 key 存在的,而value统一都是 PRESENT
 private static final Object PRESENT = new Object();

第一个定义一个 HashMap,作为实现 HashSet 的数据结构;第二个 PRESENT 对象,因为前面讲过 HashMap 是作为键值对 key-value 进行存储的,而 HashSet 不是键值对,那么选择 HashMap 作为实现,其原理就是存储在 HashSet 中的数据 作为 Map 的 key,而 Map 的value 统一为 PRESENT(下面介绍具体实现时会了解)。

3、构造函数

①、无参构造

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

直接 new 一个 HashMap 对象出来,采用无参的 HashMap 构造函数,具有默认初始容量(16)和加载因子(0.75)。
②、指定初始容量

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

③、指定初始容量和加载因子

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

④、构造包含指定集合中的元素

public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

集合容量很好理解,这里我介绍一下什么是加载因子。在 HashMap 中,能够存储元素的数量就是:总的容量*加载因子 ,新增一个元素时,如果HashMap集合中的元素大于前面公式计算的结果了,那么就必须要进行扩容操作,从时间和空间考虑,加载因子一般都选默认的0.75。

4、添加元素

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

通过 map.put() 方法来添加元素,在上一篇博客介绍该方法时,说明了该方法如果新插入的key不存在,则返回null,如果新插入的key存在,则返回原key对应的value值(注意新插入的value会覆盖原value值)。

也就是说 HashSet 的 add(E e) 方法,会将 e 作为 key,PRESENT 作为 value 插入到 map 集合中,如果 e 不存在,则插入成功返回 true;如果存在,则返回false。

5、删除元素

public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
}

调用 HashMap 的remove(Object o) 方法,该方法会首先查找 map 集合中是否存在 o ,如果存在则删除,并返回该值,如果不存在则返回 null。

也就是说 HashSet 的 remove(Object o) 方法,删除成功返回 true,删除的元素不存在会返回 false。

6、查找元素

public boolean contains(Object o) {
    return map.containsKey(o);
}

调用 HashMap 的 containsKey(Object o) 方法,找到了返回 true,找不到返回 false。

7、遍历元素

  HashSet<Integer> set = new HashSet<>();
  set.add(1);
  set.add(2);
  //增强for循环
  for(Integer i : set){
      System.out.println(i);
  }
  //普通for循环
  Iterator<Integer> iterator = set.iterator();
  while (iterator.hasNext()){
      System.out.println(iterator.next());
  }

参考文档:https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值