HashSet源码解析
来源:互联网 发布:旅游大数据第一股 编辑:程序博客网 时间:2024/05/29 20:00
-HashSet介绍
上一篇文章我们介绍了HashMap的特性,如果你了解了HashMap的源码,就会觉得HashSet真没有什么可以看得,因为它的底层全是用HashMap实现的。我们按照惯例,依旧先看官方的解释:
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
此类为基本操作提供了稳定性能,这些基本操作包括 add、remove、contains 和 size,假定哈希函数将这些元素正确地分布在桶中。对此 set 进行迭代所需的时间与 HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。
官方的解释很清楚,HashSet是由HashMap实例支持的,我们直接来看代码。
-HashSet定义
public class HashSet<E>//很多方法在AbstractSet<E>已经实现了,例如addAll方法 extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
-成员变量
//这个就是HashSet核心的底层的HashMap private transient HashMap<E,Object> map; //由于HashSet的元素都是作为Map的key来存储,所以这个变量其实是一个虚拟的value,每一个HashSet的值对应的value都是它,我们会在add方法中看的更清晰。 private static final Object PRESENT = new Object();
-构造函数
构造函数就更没有新意了,全是对应new一个HashMap
public HashSet() { map = new HashMap<>(); } public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
我对HashMap的解析的文章会在本文后面放一个链接,感兴趣的朋友可以对照这HashMap来看。
-成员函数
//从add方法可以看出,向HashSet添加一个元素实际上是向HashMap中添加一个键值对,key就是要添加的元素,value是一个固定值,这也解释了HashSet中为什么不能放重复的元素,因为HashMap的key不会重复 public boolean add(E e) { return map.put(e, PRESENT)==null; }
//从以下函数可以看出,有关于对HashSet的操作,实际上都被适配为对HashMap的操作,包括hash的方法,桶的结构,扩容的机制都是跟HashMap一样,因为在我的理解,HashSet就大概等于是HashMap的适配类。public int size() { return map.size();}public boolean isEmpty() { return map.isEmpty();}public boolean contains(Object o) { return map.containsKey(o);}public boolean remove(Object o) { return map.remove(o)==PRESENT;} public void clear() { map.clear();}
总结:由以上分析我们可以看出,HashSet的底层完全是由HashMap来支持的,HashSet把要添加的元素作为HashMap的key,存入键值对中(value是一个固定值PRESENT ),这也是HashSet为什么没有重复值的原因,因为HashMap的key不能重复,在我的理解,HashSet就大概等于是HashMap的适配类。
这里是我有关于HashMap的文章,有想理解HashMap底层实现的朋友可以看一看
HashMap源码分析
- hashset 源码解析
- HashSet源码解析
- HashSet源码解析
- HashSet源码粗略解析
- Java HashSet源码解析
- HashSet源码解析
- HashSet类源码解析
- 源码解析-集合-HashSet
- HashSet源码解析
- HashSet源码解析
- HashSet源码解析
- HashSet<T> 源码解析
- c#HashSet源码解析
- Set之HashSet源码解析
- JDK之Hashset源码解析
- java.util.HashSet源码解析
- JDK源码解析之HashSet
- JDk Set及HashSet源码解析
- spring activeMQ 整合(三): 确认机制ACK(收到消息后,应该有一个回应也就是确认答复)
- 01.认识java
- 【深度学习】基于深度学习的目标检测研究进展
- 写代码、写文章、运营等等几个常用的工具或者好文章
- HDU 2013
- HashSet源码解析
- redis学习
- @NotNull 、@NotBlank、@NotEmpty三者的区别
- Java虚拟机1
- Struts2学习笔记(十二)——文件上传
-  |"|&|<|>等html字符转义
- struts2中请求包含参数如何处理
- JSP九个内置对象及其常用方法
- UGUI绘制过多点连续的平滑曲线