课程介绍
课程目录
用户评论
课程介绍
课程目录
用户评论

你将获得

  • HashMap 基本结构
  • HashMap 源码解析
  • 红黑树、二叉树与平衡二叉树
  • 2-3 树

教学服务

  • 名师授课,不走弯路
  • 高质量技术交流群,圈内大佬云集

讲师介绍

老师头像

高杰

Kotlin 专家、谷歌开发者社区讲师
Kotlin 专家,HenCoder 及码上开学成员之一,受邀担任谷歌开发者社区讲师。拥有丰富的 Android 开发经验,擅长 Android 组件化开发及性能优化,对布局优化、过度绘制、内存泄露等有比较深入的研究。具备丰富的大型互联网金融项目架构设计经验。

课程详情

大家都在问

想了解高级开发课

294人在问去咨询

想了解Compose

294人在问去咨询

怎么加入技术交流群?

294人在问去咨询

知识星球是什么?

294人在问去咨询

HashMap 1.8 源码解析 - 高杰视频文稿

好,在上一小节我们已经看过hashmap1.7的核心源码了,现在我们来看一下1.8hash map在1.8中呢,有哪些地方相对于1.7做了改进的,同样的,我们先来看一下它的构造器,可以看到构造器里面只有一行代码,它设置了满载率值呢,还是0.75,他没有在构造方法中设定初始容积和初始的临界值,那么我们去成员变量看看是否都复制了,首先,这是初始阈值,是没有赋值的,也是零,这里有初始的容积,它的值还是一左移四位,也就是16,那构造方法我们已经看完了,我们可以去看一下他的破的方法,Put方法我们1.7不一样,在铺的内部呢,会调用这个put val方法,并且在put file方法的第一个参数上调用了hash方法,可以看到先对这个key进行了一次hash,他这个hash呢,只有两行,比1.7要简单得多,这个1.7里面是这样的,1.7里面甚至还会用到这个hash c的这个需要GVM配置的因素,但是在1.8的时候已经抛弃掉这个方案了,就是简单的又16位加上异或的运算,不过呢,Hash的目地是没有改变的,还是没有直接使用hash code目的也就是为了扰乱hash,让更多的二进制位参与到后面,需要进行根据数组长度找索引的与运算,尽量让元素散落在数组不同的索引上来看put方法,他往里面传入了hash key value,另外还有两个玻璃的参数,快速地解释一下这两个参数是干嘛用的,这个only FAB sent后面的这个absent呢,就是你侦探小说里面的呢,不在场,证明他不在场,结合一下的only if absent,也就是只有不在场的时候才会做什么事了,那它的作用是什么呢,它的作用是可以让hash map里面已经有相同的key时,注意是相同的key,不是hash不要覆盖旧的值了,只有不存在值的时候才可以进行添加值,那1.7的时候是直接覆盖的,1.8的话可以不覆盖,但是你调用普通的PU的时候,它默认传入的是false,如果想让他传入true,也就是利用这个不覆盖的功能的话,那么应该调用这个put if absent这个方法,另外一个参数effect,这个呢,在hash map里面其实是没有用到的,它是用来给hash map的子类linked hash map来用的,这个linked hash map在元素达到某个条件的时候,比如说你设定了100个上线,那么你再添加第101个值的时候,就会对最老的那个节点进行删除,其实也就是这个单词的意思,驱逐、放逐,非常形象,我们正式进入这个port这个源码,看一下这个put val,这个方法比1.7的破的方法要长的很多,不过我们慢慢看过来,其实都不复杂的,首先627行这地方,一行代码申请了四个变量,特别是最后面用一个in TE,同时证明了N和I,看起来很炫酷,但是还是想给大家提个醒,我们自己写代码的时候别搞这种套路,你老老实实用四行代码,朴实无华且枯燥的给他生出来,这样阅读代码的人也不容易漏看,另外呢,你命名变量的时候也不要这样太随意了,像这里的变量命名,说实话的,你这一个node p,你如果命名合适一点,其实可以让人更加的容易理解,你单独一个屁,让读代码的人其实很头疼,然后我们继续往下面看,628行和629行这两行,在这个if判断上面呢,会将这个成员变量table赋值给这个局部变量tape,并且判断这个tape是不是为now,如果为now,那就会进入这个if判断,会对这个cap重新调用re side进行赋值,如果这个tape不为no呢,那么就会判断他这个数组的长度是不是为零,如果为零,那还是要需要调用这个re size的,在1.7中呢,也有个方法叫做re size,它的作用是扩容,只有在满足扩容条件的时候才会执行到,而在1.8的时候呢,这里的re size不仅有扩容的代码,初始化速度的操作也会在里面完成,当第一次执行这个recess的时候,其实也就是执行初始化数组的代码,那从这里也可以看出来一点吧,里面的数组和一点七一样,会在第一次添加元素的时候才可以创建出来,而不是创建hash map的时候直接创建的数组,1.8的resigned相对于1.7要复杂得多,这也是因为扩容和初始化的代码都在这个里面,如果我们添加的是第一个元素,那么会进入这个re size,在这个reset内部我们看一下是如何进行初始化的,首先记录老的这个数组,保存在这个局部变量old chap上,然后获得一下这个老的数组的长度,这地方他这个执事nor,那所以这个值肯定是为零,接着呢,记录一下成员变量上的这个预值,我们前面说到过,这个阈值并没有初始化,所以默认为零,然后这地方定义新的速度