JDK 源码复习 util包 02 Set相关

JDK 源码复习 util包 02 Set相关

HashSet:

JDK 源码复习 util包 02 Set相关

和前面介绍的大多数集合一样,HashSet 也实现了 Cloneable 接口和 Serializable 接口,分别用来支持克隆以及支持序列化。还实现了 Set 接口,该接口定义了 Set 集合类型的一套规范。

①:实现了Serializable接口,表明它支持序列化。
②:实现了Cloneable接口,表明它支持克隆,可以调用超类的clone()方法进行浅拷贝。
③继承了AbstractSet抽象类,和ArrayList和LinkedList一样,在他们的抽象父类中,都提供了equals()方法和hashCode()方法。它们自身并不实现这两个方法,(但是ArrayList和LinkedList的equals()实现不同。你可以看我的关于ArrayList这一块的源码解析)这就意味着诸如和HashSet一样继承自AbstractSet抽象类的TreeSet、LinkedHashSet等,他们只要元素的个数和集合中元素相同,即使他们是AbstractSet不同的子类,他们equals()相互比较的后的结果仍然是true。下面给出的代码是JDK中的equals()代码:
从JDK源码可以看出,底层并没有使用我们常规认为的利用hashcode()方法求的值进行比较,而是通过调用AbstractCollection的containsAll()方法,如果他们中元素完全相同(与顺序无关),则他们的equals()方法的比较结果就为true。
①HashSet内部通过使用HashMap的键来存储集合中的元素,而且内部的HashMap的所有值
都是null。(因为在为HashSet添加元素的时候,内部HashMap的值都是PRESENT),而PRESENT在实例域的地方直接初始化了,而且不允许改变。
②HashSet对外提供的所有方法内部都是通过HashMap操作完成的,所以,要真正理解HashSet的实现,只需要把HashMap的原理理解即可。我也对HashMap做了分析

说明:

  • 代码块1:HashSet中map的默认大小为HashMap的默认值,即容量为16,负载因子为0.75。
  • 代码块2:HashSet中map的容量最小值为16。

七、分析总结

HashSet的源码更多的是对HashMap的封装,简单总结一下:

HashSet是基于HashMap实现的,不能有重复的元素;
HashSet可以插入null,但只能有一个;
HashSet不是线程安全的;
HashSet,HashMap都是hash表,而hash实现的容器最重要的一点就是可以快速存取。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

JDK 源码复习 util包 02 Set相关