HashSet 、LinkedHashSet 源码级详解

简介: HashSet 、LinkedHashSet 源码级详解

Set 集合类体系如下:

HashSet -- 无序、不重复、无索引

LinkedHashSet -- 有序、不重复、无索引

TreeSet -- 可排序、不重复、无索引

HashSet

HashSet 底层采用 哈希表 存储数据

哈希表组成

JDK8 之前  -- 数组 + 链表

JDK8 之后  -- 数组 + 链表 +红黑树

一开始会把元素存储在数组中,但是哈希表会出现同一个索引位置要存储多个元素的情况,因此要将同一个索引位置的多个对象用链表或红黑树进行存储

哈希表的核心 -- 哈希值

哈希值我们可以理解为对象的整数形式

因为在哈希表存储的时候,不是从索引零开始按序存储的,而是根据公式

int index = (数组长度 - 1 )& 哈希值

index就是对象存储的位置

对象可以根据 hashCode 方法计算出哈希值,该方法定义在Object类中,因此所有对象都可调用,默认使用地址值进行计算,但是一般情况下用对象的地址值计算哈希值的意义不大,因此一般情况下会重写 hashCode 方法,利用对象内部属性计算哈希值

关于 hashCode 方法 重写,最重要的是 hashCode 方法和 equals 方法的联系,可以参考以下博客

我们对 对象相等 的定义是:当两个对象 equals 返回 true 时,则两个对象就是相同的

但是当两个对象不相等时,可能会得到相同的哈希值

哈希表存储的原理:

通过哈希值计算出存储的位置,如果该位置为null,则直接存入;

如果不为null,则调用equals方法(不为null说明多个对象的哈希值相等,但是哈希值相等不代表元素相等,元素是否相等的标准由equals判断),如果该位置存在equals为true的元素,则不存储,如果没有则存储(以链表或红黑树的形式存储)

所以从上面看出,哈希值具有两个作用,一是计算出存储位置,二是初步判断哈希表中是否存在相同元素


正是因为哈希表具有不存储相同对象的特点,HashSet才能做到不重复


又因为哈希表是数组+链表+红黑树,并且不是从索引0开始按序存储,所以HashSet是无序的、无索引的


如下图,在遍历的时候,会先查看0索引位置,没有元素,那么查看1索引位置,遍历该链表,继续查看2索引位置... 以此类推,因此遍历的结果是 黄 -> 橙 -> .. -> 深蓝 -> 浅蓝 ,而我们存储的顺序可能是 橙 -> 浅蓝 -> ... -> 蓝->黄

LinkedHashSet

本质上跟 HashSet 相同,只不过多了个双链表的机制记录储存的顺序

现在我们要将这四个元素存入哈希表中

现在存入第一个元素,此时还有一条双向链表,双向链表的头结点指向该元素

存入第二个元素,此时,第一个元素会记录下第二个元素的地址值,第二个元素也会记录第一个元素的地址值,这就形成了一个双向链表


存入第三个元素,第三个元素和第四个元素间同样会相互记录地址值

存入第四个元素

接下来要遍历的时候,不再和HashSet相同,而是直接从头节点开始遍历该双向链表,最后得到的结果就是有序的

目录
相关文章
|
2月前
|
Java uml
|
2月前
|
设计模式
LinkedHashSet源码详解
LinkedHashSet源码详解
|
16天前
|
存储 安全 Java
Java集合篇之set,面试官:请说一说HashSet、LinkedHashSet、TreeSet的区别?
Java集合篇之set,面试官:请说一说HashSet、LinkedHashSet、TreeSet的区别?
13 0
|
17天前
并发编程之的HashSet和HashMap的详细解析
并发编程之的HashSet和HashMap的详细解析
9 0
|
7月前
|
存储 算法 Java
java集合框架Map之HashMap底层原理解析
阈值(threshold) = 负载因子(loadFactor) x 容量(capacity) , 当HashMap中的table数组(桶)的长度 >= 阈值的时候就会自动触发扩容机制
45 0
|
存储 索引
HashMap、HashTable和HashSet区别源码分析
HashMap、HashTable和HashSet区别源码分析
74 0
HashMap、HashTable和HashSet区别源码分析
|
存储 算法
面试题:说一下HashMap和HashSet的实现原理?
面试题:说一下HashMap和HashSet的实现原理?
71 0
|
存储 Java Android开发
Java集合学习5:Map-HashMap、Hashtable
说白了,Map就是 键值对,存储一对数据 。允许用null作为key或者value。
Java集合学习5:Map-HashMap、Hashtable
|
存储 算法 安全
Java集合(5)--Set接口及其实现类HashSet、LinkedHashSet和TreeSet
Java集合(5)--Set接口及其实现类HashSet、LinkedHashSet和TreeSet
93 0
Java集合(5)--Set接口及其实现类HashSet、LinkedHashSet和TreeSet
|
缓存 Java 程序员