hashmap数据结构详解(四)之hashmap过程综述

 

hashmap数据结构详解(一)之基础知识奠基

hashmap数据结构详解(二)之走进JDK源码

hashmap数据结构详解(三)之hashcode实例及大小是2的幂次方解释

hashmap数据结构详解(四)之hashmap过程综述

 

关于hash方式前面已经说过了。首先现在有一对键值对(123,“hello”)

hash算法:

jdk中提供了根据key值计算出一个当前独一无二的hashcode的方法。

基槽计算:

见第二节

使用put方法时:

首先根据key值即(123)计算相应的hashcode值。再由hashcode值计算得到“基槽”的位置,该基槽延伸出一个节点存储,基槽只是存了基槽的index,并不是存key值,所有的键值对都是以节点形式存在链表或者红黑树里面。

见下图:

 

 

此时可能出现一个问题:

即有多个key值为(123)的键值对的情况。此时的hashcode值是一样的,一般有“链表”和“再探测”(再一次计算基槽,根据相应的探测函数)两种方式,多为“链表法”。

“链表法”解决hashmap存储的冲突:将hashcode值相同的存在之后的链表中即可(存的也是节点),且在jdk1.8中,链表改为了红黑树存储。

 

 

使用get方法:

不存在冲突的情况下,直接根据get方法,例如:get(“123”):

关于此处时间复杂度为:1

此处的get方法是根据key(123)再次计算hashcode值和基槽的位置,由此可以直接获取虚拟存储位置,因此不需要遍历查找,时间复杂度很低。

此处的问题:

多个value值在同一个key上面(即put时发生了冲突)

此时只能进行节点的遍历查询。

先看源码:

get方法,返回的是值或者为null;

----------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------

getNode方法:根据hashcode值和对应的key值,由hashcode找到数组的基槽位置,根据key值找到对应的节点,找到对应节点后,可以获得所需要的值。

 

误区:

1、相同的key值时,记录会覆盖,但是可以通过重写方法的方式修改覆盖机制。

2、不同的key值也可能产生相同的hashcode值。

3、当所有的记录数目大于阈值(数组大小x设定的加载因子时),会引起扩容机制。

猜你喜欢

转载自blog.csdn.net/whandwho/article/details/81086638