HashMap1.7和1.8的区别

HashMap1.7和1.8的区别

1.JDK1.7用的是头插法,而JDK1.8及之后使用的都是尾插法

那么为什么要这样做呢?因为JDK1.7是用单链表进行的纵向延伸,当采用头插法时,再多线程环境下并发扩容的时候,会容易出现环形链表死循环问题。但是在JDK1.8之后使用尾插法,能够避免出现逆序且链表死循环的问题。

2.扩容流程不同:

1.8是扩容前插入键值,连同旧的键值一起转移,一起计算,1.7是扩容后,扩容后进行插入,旧数据转移到新的数组之后,然后再单独计算插入的位置。为什么1.8是插入之后再整体计算扩容,主要是为了减少红黑树和链表来回转换的频率

3.扩容后数据存储位置的计算方式也不一样:

要说清楚这个,先得说说HASHMAP如何求桶的位置

HashMap求桶的位置一共分为三个过程:

1)求key的hashcode 2)将hashcode的高16位和低16位进行异或操作。

至此我们完成了hash方法,求得了该元素的hash值。源码在下方

static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

3)(n - 1) & hash ,将hash值与length-1进行与操作,求桶的位置

 if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);

无论是JDK7还是JDK8,HashMap的扩容都是每次扩容为原来的两倍,即会产生一个新的数组newtable,我们需要把原来数组中的元素全部放到新的只不过元素求桶的位置的方法不太一样。

在JDK7中就是按照我上述写的三个步骤重新对元素求桶的位置,但是第三步与的值是新的数组的长度-1,也就是newCap-1。

但是JDK8中就不是和newCap,而是直接和oldCap进行与运算,也就是与旧数组的长度(oldCap)进行与操作。下面的是伪代码:

if ((e.hash & oldCap) == 0) {
newTab[j] = loHead;
}else{
​
newTab[j + oldCap] = hiHead;
}

与oldCap与的结果如果是0,那么就代表当前元素的桶位置不变。 反之,那么扩容后桶的位置就是原位置+原数组长度(oldCap)

4.数据结构不同

JDK1.7的时候使用的是数组+ 单链表的数据结构。但是在JDK1.8及之后时,使用的是数组+链表+红黑树的数据结构(当链表的深度达到8的时候,也就是默认阈值,就会自动扩容把链表转成红黑树的数据结构来把时间复杂度从O(n)变成O(logN)提高了效率),小于6的时候,又会转换为链表。为什么是8,容器中节点分布在hash桶中的频率遵循泊松分布,桶的长度超过8的概率非常非常小。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/634957.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go 语言(九)----struct

定义一个结构体 type Book struct {title stringauth string }结构体使用 package mainimport "fmt"//定义一个结构体 type Book struct {title stringauth string }func main() {var book1 Bookbook1.title "Golang"book1.auth "zhang3"fmt…

使用 TiUP 部署 TiDB 集群

TIDB优点 支持分布式且支持事务的关系型数据库,不用考虑分库分表 同时满足了可伸缩,高可用,关系型,支持事务。 基本上按官网的文档来就行了。 在线部署 以普通用户身份登录中控机。以 tidb 用户为例,后续安装 TiUP …

用git bash调用md5sum进行批量MD5计算

对于非常大的文件或者很重要的文件,在不稳定的网络环境下,可能文件的某些字节会损坏。此时,对文件计算MD5即可以校验其完整性。比如本次的 OpenStreetMap 导出包,我的学弟反馈通过网盘下载无法解压,并建议我增加每个文…

MOS管和IGBT管的定义与辨别

MOS管和IGBT管作为现代电子设备使用频率较高的新型电子器件,因此在电子电路中常常碰到也习以为常。可是MOS管和IGBT管由于外形及静态参数相似的很,有时在选择、判断、使用容易出差池。MOS管和IGBT管可靠的识别方法为选择、判断、使用扫清障碍&#xff01…

android使用相机 intent.resolveActivity returns null

问题 笔者使用java进行android开发,启动相机时 intent.resolveActivity returns null takePictureIntent.resolveActivity(getPackageManager()) null详细问题 笔者使用如下代码启动相机 // 启动相机SuppressLint("LongLogTag")private void dispatc…

【LGR-172-Div.4】洛谷入门赛 #19(A—H,c++详解!)

文章目录 【LGR-172-Div.4】洛谷入门赛 #19A.分饼干 I题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示样例解释 1样例解释 2数据范围与约定思路: 代码 B.分饼干 II题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样…

2024--Django平台开发-订单项目管理(十四)

day14 订单管理系统 1.关于登录 1.1 UI美化 页面美化,用BootStrap 自定义BooStrapForm类实现。 class BootStrapForm:exclude_filed_list []def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# {title:对象,"percent":对象}fo…

c++ extern

在 C++ 中,对于使用extern 关键字,我们再熟悉不过了。接下来我们一起探讨一下关于extern 关键字的使用方法以及应用场景。 变量的声明 当你在多个文件中使用同一个全局变量时,你需要在使用它们的文件中用 extern 关键字进行声明,而在一个文件中定义它(分配存储空间)。假…

【推荐系统】item-id 作为特征的意义

因为其实 模型本身就是 基于记忆(拟合) 的, 是有一些 预测/泛化 的能力,但不影响模型在记忆的出发点, 所以把item-id embedding后作为特征,就是一个让模型记住每个item信息的方式

Python--对于类的一些练习

#定义一个类 class Person():def eat(self):print(我喜欢吃零食)def drink(self):print(我喜欢喝冰红茶) #类的实例化 p1 Person() p1.eat() p1.drink() #定义一个类 class Person():def speak(self):print(self)print(很高兴见到你) #类的实例化 p2 Person() print(p2)#打印…

电路复习总结

又到了个人最喜欢的电路复习环节,废话不多说一个个复习过来 1.电路基本概念 2.向量表示 现在在看美少女老师教学某一种正弦交流电的办法学的就很舒服 知道复数和极坐标还挺重要可以便于后面数值计算 2024年1月18日19:44:57 根本整理不出来什么东西i 在学习中逐…

测试 ASP.NET Core 中间件

正常情况下,中间件会在主程序入口统一进行实例化,这样如果想单独测试某一个中间件就很不方便,为了能测试单个中间件,可以使用 TestServer 单独测试。 这样便可以: 实例化只包含需要测试的组件的应用管道。发送自定义请…

算法训练营Day44

#Java #动态规划 Feeling and experiences: 最长递增子序列:力扣题目链接 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不…

c/c++中不同文件中的同名变量一定会redefine吗

今天讨论一个问题,那就是在 c/c 中,比如两个文件中的同名全局变量,一定会造成 redefine 的问题吗? 我们知道,在 c 和 c 中,编译器对符号的 mangling 是不同的,c 中通过下划线前缀加上符号的名称…

中移(苏州)软件技术有限公司面试问题与解答(1)—— 可信计算国密标准

接前一篇文章:中移(苏州)软件技术有限公司面试问题与解答(0)—— 面试感悟与问题记录 本文参考以下文章: 信息安全第五篇(国密加密算法)_domestic encryption algorithm-CSDN博客 …

音视频编解码学习记录

目录 学习资料个人git仓库 文章 学习资料 个人git仓库 标准,资料,笔记: https://gitee.com/fedorayang/video_and_audio_codec.git 文章 理解低延迟视频编码的正确姿势: https://cloud.tencent.com/developer/article/1358721

龙芯+RT-Thread+LVGL实战笔记(30)——电子琴演奏

【写在前面】正值期末,笔者工作繁忙,因此本系列教程的更新频率有所放缓,还望订阅本专栏的朋友理解,请勿催更。笔者在此也简要声明几点: 有些硬件模块笔者并没有,如LED点阵、压力传感模块、RFID模块等,因此这些模块的相关任务暂时无法给出经过验证的代码。其实,教程进行…

Webpack5入门到原理11:处理 js 资源

有人可能会问,js 资源 Webpack 不能已经处理了吗,为什么我们还要处理呢? 原因是 Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行&#xff0c…

排序之归并排序

在计算机科学中,排序是一种常见的操作。它用于将一组元素按照一定的顺序排列。归并排序是一种非常有效的排序算法,其时间复杂度为O(nlogn),空间复杂度为O(n)。本文将详细介绍归并排序的工作原理和实现方法。 归并排序的工作原理 归并排序的…