zoukankan      html  css  js  c++  java
  • HashSet与HashMap源代码深度剖析

    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,则将该对象放到数组当中,然后将数组中该位置放到数组当中,然后将数组中该位置以前存在的那个对象连接到此对象的后面。
  • 相关阅读:
    数据结构与算法_20 _ 散列表(下):为什么散列表和链表经常会一起使用?
    数据结构与算法_19 _ 散列表(中):如何打造一个工业级水平的散列表?
    数据结构与算法_17 _ 跳表:为什么Redis一定要用跳表来实现有序集合?
    数据结构与算法_18 _ 散列表(上):Word文档中的单词拼写检查功能是如何实现的?
    数据结构与算法_16 _ 二分查找(下):如何快速定位IP对应的省份地址
    数据结构与算法_15 _ 二分查找(上):如何用最省内存的方式实现快速查找功能
    线程池ThreadPoolExecutor源码详解
    用信鸽来解释 HTTPS
    并发集合类之图解CopyOnWriteArrayList
    认识RabbitMQ从这篇文章开始
  • 原文地址:https://www.cnblogs.com/webor2006/p/8995256.html
Copyright © 2011-2022 走看看