| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 【Java se】简述哈希表(主要描述新增过程) -> 正文阅读 |
|
[数据结构与算法]【Java se】简述哈希表(主要描述新增过程) |
目录 ? 数组与链表数组? ? ? ? 在学习Java的初期,我们认识了一种能够存储多个数据的数据结构——数组,其中数据在空间中是连续的,因其具有索引值的原因,它在根据索引值查询数据时拥有着很大的优势,但是在对内容进行增、删操作的时候却是很复杂的。 ? ? ? ? 我们简单创建一个长度为5的数组: ? ? ? ? 删除索引值为2元素时,数组的变化过程。 ? ? ? ? ?数组新增过程与删除过程类似,比如要在索引值为2的位置新增元素,索引值>=2的所有元素都要后移一个,十分复杂,效率低。 ? 链表? ? ? ? 而链表是每个值的空间可以不连续的一种数据结构。 ????????链表有着增删快的特点。 ????????增加元素时:①更改上一个元素的指向地址值(更改为新增元素的地址值) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ②更改增加元素的指向地址值(更改为上一个元素原本指向的地址值) ? ? ? ? 删除同理。 ????????但是链表在查询数据时没有优势,只能通过逐个遍历的方式来进行查询。 ????????为提高效率有双向链表的存在,指从两个方向来遍历查找元素,但是速度不会比数组快。? ? 哈希表? ? ? ? 现在我们引入这样一个数据结构,它是由数组和链表/红黑树结构组合而成的。 ? ? ? ? 当我们学习到集合时,会学到Set接口的一个实现类:HashSet,它的底层就是使用了哈希表(HashMap)的数据结构,它的特点是:无索引值,元素不重复。 ? 哈希表的新增过程
? ? ? ? 我们来创建一个HashSet类型的集合,根据关键性原码来简述一下元素的新增过程。
? ? ? ? ①hash方法对新增的值进行了一定的操作,我们新增的元素不为null,则通过(h = key.hashCode()) ^ (h >>> 16)计算元素的哈希值,返回给put方法。
? ? ? ? 计算完hash值将结果传入?putVal方法。
? ? ? ? ②添加第一个值时数组还未创建,则第一次添加后,将数组长度初始化为16,数组类型为java.util.HashMap$Node。
? ? ? ? Node类型中有个成员变量next,并且类型也是Node,可知这是一个单向链表结构,next表示指向的下一个元素。
? ? ? ? ③数组已经创建,数组长度为16。上述计算出元素伪索引的操作课简单描述为hash%数组长度。因此可得出0~15之间的某一个值。
????????因为是添加的第一个元素,索引值位置的值一定为null,此时会new一个Node类型的对象。 ???????? ? ? ? ? ?进行操作后得出索引值位置: ? ? ? ? ?④如果新增的位置为null,则直接新增。
? ? ? ? ⑤如果新增位置不为null时,因为Set接口中规定元素是不能重复的,则通过p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))进行元素是否重复的判断。 ????????因为Node中存的都是引用数据类型,因此==比较的是地址值。 ????????简单来说就是将(哈希值相同 &&(地址值相同 ||? equals值相同)) 值作为判定条件。 ? ? ? ? 我们认为两个值地址相同或者值相同,如String中,两个对象的地址值不同,但是当他们是指向同一个字符串常量池的位置时,通过equals比较时值相同,我们便可以说这两个值是相等的。
? ? ? ? ? 可以看出当索引值位置有值时会添加到该索引值位置链表的最后面。(即next为null的地方) ? ? ? ? 我们也可以看出来链表在空间上的位置时不连续的。
?哈希表是如何进行扩容的(简述)
?
? 关于哈希表的一些其他问题1.为什么HashSet是无序的? ? ? ? 因为先新增的元素可能算出的索引值靠后,后新增的元素值算出来可能在前,而获取元素的值是从前向后的(先获取索引值为0的)。 ? ? ? ? 从我们举的例子可以看出来,存入的顺序为10,20,30。而输出(获取)的结果为:[20, 10, 30]。 ? 2.为什么哈希表没有索引值? ? ? ? 我们在上面说的都是伪索引,是Node类型数组的索引值,哈希表底层是Node类型的数组,而Node是链表结构,每个索引值下面可能会有多个元素,因此获取哈希表中的元素不能像数组一样通过下标获取。 ? ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/28 18:17:54- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |