先欣赏个美景~~
前面章节回顾一下:
介绍了集合ArrayList、LinkedList、HashMap以及LinkedHashMap和并发安全的ConcurrentHashMap,还有一些其它的集合
接下来我们来分析Set,继承Collection的集合,主要介绍HashSet、TreeSet、LinkedHashSet几个常用集合

先来大致了解下这三个集合:
HashSet集合,底层是HashMap,哈希表+红黑树
TreeSet集合,底层是一个自平衡红黑树,保证元素的顺序
LinkedHashSet集合:底层是哈希表+双向链表组成

这篇文章主要说明它们如何实现,需要注意什么,以及应用场景~
HashSet解析
HashSet定义:
public class HashSet<E> extends AbstractSet<E>implements Set<E>, Cloneable, java.io.Serializable {}{
HashSet结构图:

HashSet简介:
HashSet实现Set接口,不保证迭代顺序,允许元素为null。
底层实际上是一个非同步的HashMap实例,初始容量非常影响迭代性能。
HashSet除了在元素的存储上是无序的以外,还是不能够存储重复的元素。
HashSet实际上就是封装了HashMap,操作HashSet元素实际上就是操作HashMap。这也是面向对象的一种体现,重用性贼高!
不能重复元素是根据元素继承的两个方法来判断hashCode和equals,当存储元素时,首先判断要存入的元素和已存在的元素的哈希值是否相同,若不相同存入,若相同则利用equals判断两个元素是否相同,若不相同,则存入,若相同则放弃。而hashCode和equlas是在存入元素自动调用的

原来如此啊!HashSet内部竟然是HashMap构造的,内部的很多操作也都是直接用的HashMap来实现的。HashSet就是用的HashMap的Key,利用的它的Key的不可重复性。
有人可能会疑问,那既然采用的是HashMap,我们知道Map是Key-Value键值对,HashSet对应HashMap的Key,那Value值呢?

Value是一个Object对象,所有的Value都是它,是不是豁然开朗~

TreeSet
TreeSet定义:
public class TreeSet<E> extends AbstractSet<E>implements NavigableSet<E>, Cloneable, java.io.Serializable { }
TreeSet结构图:

TreeSet实现NavigableSet接口,可以实现排序功能,底层实际上是非同步的TreeMap实例,即红黑树存储。
TreeSet中存储的类型必须是一致的,不能一下存int,一下又存string。

原来TreeSet内部是由TreeMap构造的啊,Set和Map可真是相亲相爱的一家子啊

LinkedHashSet
LinkedHashSet定义:
public class LinkedHashSet<E> extends HashSet<E>implements Set<E>, Cloneable, java.io.Serializable { }

看到这里可能就明白了,LinkedHashSet继承自HashSet,底层也是HashMap实例,不过这里它多维护了一个双向链表(其实就是LinkedHashMap实例),不由的感慨,Set就是由Map构建的啊!
LinkedHashSet底层实际上是一个HashMap+双向链表实例(其实就是LinkedHashMap)。
LinkedHashSet迭代有序,允许null,性能比HashSet差一丢丢,因为要维护一个双向链表。
初始容量与迭代无关,LinkedHashSet迭代的是双向链表。
唠叨
你知道的越多,你不知道的也越多。
总结:我们可以得出Set集合的底层就是由Map来构建的,所以我也没有太多的源码分析,也没啥必要,想了解源码的可以看我前几篇,下面总结下Set集合常用的三个子类吧
HashSet无序,允许null,底层是HashMap(散列表+红黑树),非线程同步
TreeSet有序,不允许null,底层是TreeMap(红黑树),非线程同步
LinkedHashSet允许null,底层是HashMap和双向链表,非线程同步
学会了之后呢~








