HashSet源码分析:

先来看一下它的构造方法:

呃~~居然它的底层是用HashMap来实现的,颠覆三观,那它究竟是如何来用的呢?继续来往下跟:

对于HashSet而言是没有key->value的结构的,那它是怎么跟HashMap关联到一块的呢?接着得查看add方法了:

也就是将我们往HashSet添加的元素是被用作HashMap的key,而HashMap的Value是一个常量,看一下它长啥样:

而这个字段也说明了,它是一个"Dummy value",也就是假的值,因为对于HashSet来说,只需要用到HashMap的key就行了,对于value不关心。

接着再来看一下删除元素的实现:

当然都是借助于HashMap来删除喽~


那它的其它方法其上差不多了,既然底层是由HashMap来实现的,那接下来就得探究一下HashMap的底层原理喽。

HashMap源码分析:

先来查看一下空的构造方法:

然后一句句代码来分析一下:

这有什么意义呢?这是因为通过散列来决定当前的元素达到总集合的75%时,则认为集合就快满了,所以就要考虑给集合进行扩容了,

这是干嘛滴,先不管,其中又用到了一个新的常量:

目前貌似一脸懵逼,不晓得这些变化是干嘛的,先放着,继续往下分析:


所以整个构造函数是初始化了一个长度为16的Entry类型的数组,那这个Entry又是啥呢?

接着再来分析放里面放元素的方法:

呃,貌似很复杂,但要想搞清楚原理必须得硬着头皮去读它,所以一句句来:

这个不太重要,往下继续:

注意:这个计算出来的并不是真正要添加的位置,真正要添加元素的位置在下一句,如下:

继续回到主流程:

那是如何添加的呢?继续查看该函数的实现,在查看之前先记住最后一个参数i,这是计算出来要存放的元素位置:

注意构造Entry的最后一个参数e:

也就是说将之前的元素做为新构建的Entry的下一个元素了,什么意思,下面用图来表示一下其添加的过程:

目前数组第一个元素已经有一个Entry1对象了,接着再put的时候散列位置时又散列到第一个元素了,此时添加时就会是:

这时就会将以前的那个元素作为新加入的Entry的next元素,因为Entry维护了一个next的引用。

总结:

  • HashSet底层是使用HashMap实现的。当使用add方法将对像添加到Set当中时,实际上是将该对象作为底层所维护的Map对象的key,而value则都是同一个Object对象(该对象我们用不上)。
  • HashMap底层维护一个数组,我们向HashMap中所放置的对象实际上是存储在该数组当中。
  • 当向HashMap中put一对键值时,它会根据key的hashcode值计算出一个位置,该位置就是此对象准备往数组中存放的位置。
  • 如果该位置没有对象存在,就将此对象直接放进数组当中;如果该位置已经有对象存在了,则顺着此存在的对象的链开始寻找(Entry类有一个Entry类型的next成员变量,指向了该对象的下一个对象),如果此链上有对象的话,再去使用equals方法进行比较,如果对此链上某个对象的equals方法比较为false,则将该对象放到数组当中,然后将数组中该位置放到数组当中,然后将数组中该位置以前存在的那个对象连接到此对象的后面。

转载于:https://www.cnblogs.com/webor2006/p/8995256.html

HashSet与HashMap源代码深度剖析相关推荐

  1. Java HashSet和HashMap源码剖析

    转载自 Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说Ha ...

  2. HashMap源代码深入剖析

    1. 概述 首先从一个例子来开始HashMap的学习 public class Test {public static void main(String[] args) {Map<String, ...

  3. 深度剖析ConcurrentHashMap

    在阅读Spring IOC源码的时候,发现了里面的map是ConcurrentHashMap.有些疑问,我们平时都使用HashMap和HashTable,我们也知道,HashMap是线程不安全的,但是 ...

  4. [Java并发包学习八]深度剖析ConcurrentHashMap

    转载----http://qifuguang.me/2015/09/10/[Java并发包学习八]深度剖析ConcurrentHashMap/ HashMap是非线程安全的,并发情况下使用,可能会导致 ...

  5. 2、深度剖析ConcurrentHashMap

    原文地址:qifuguang.me/2015/09/10/[Java并发包学习八]深度剖析ConcurrentHashMap/ 1 ConcurrentHashMap的目的 多线程环境下,使用Hash ...

  6. Java_深度剖析ConcurrentHashMap

    本文基于Java 7的源码做剖析. ConcurrentHashMap的目的 多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用Hash ...

  7. [Java并发包学习]深度剖析ConcurrentHashMap

    [Java并发包学习]深度剖析ConcurrentHashMap 概述 还记得大学快毕业的时候要准备找工作了,然后就看各种面试相关的书籍,还记得很多面试书中都说到: HashMap是非线程安全的,Ha ...

  8. 深度剖析ConcurrentHashMap(转)

    概述 还记得大学快毕业的时候要准备找工作了,然后就看各种面试相关的书籍,还记得很多面试书中都说到: HashMap是非线程安全的,HashTable是线程安全的. 那个时候没怎么写Java代码,所以根 ...

  9. libevent源码深度剖析

    原文地址:http://blog.csdn.net/sparkliang/article/details/4957667 libevent源码深度剖析一 --序幕 张亮 1 前言 Libevent是一 ...

最新文章

  1. Pytorch的网络结构可视化(tensorboardX)(详细)
  2. mysql linux改user_linux mysql误修改user表导致无法root用户登录,求大神帮助。-问答-阿里云开发者社区-阿里云...
  3. 三维激光重建原理与实现HALCON
  4. C++ 原码、反码、补码理解笔记
  5. 查看ubuntu版本
  6. 三层架构——配置文件
  7. tslib1.4安装小记
  8. 谁说docker-compose不能水平扩展容器、服务多实例?
  9. I - The Mad Mathematician FZU - 2042(未解决)
  10. Hadoop 副本存储策略的源码修改和设置
  11. 没个百来万就想自建技术团队?亲身经历告诉你,一个APP从无到有的开发到底要花多少钱!...
  12. Javascript_备忘录3
  13. uniapp换行符号_第15讲 : uni-app 组件 - 地图组件
  14. 知道python网课答案_分析最近的一个网课答案查询2.0
  15. Winodws update auto update client(wuauclt)
  16. Apifox测试Excel文件上传
  17. ai人工智能的数据服务_AI如何帮助提高企业数据质量
  18. Sql server语句(增删改查)
  19. 硬件设计之JTAG转USB转换芯片
  20. Android自定义View(一)

热门文章

  1. Hadoop Hive导入数据命令
  2. k8s service:ingress
  3. VMware vSphere中三种磁盘:精简置备/厚置备置零/厚置备延迟置零
  4. idea GsonFormat插件使用报错 StringIndexOutOfBoundsException: begin 0, end -1, length 9
  5. idea2019.x配置Gradle
  6. Python Django根据数据库表生成模型类的命令
  7. JVM 的内存模型及jstat命令的使用
  8. Dubbo 融合 Nacos 成为注册中心
  9. Java线程的等待与唤醒代码示例
  10. nodejs ajax进度条,Ajax异步文件上传与NodeJS express服务端处理的示例分析