hashmap的数据结构以及put和get

hashmap的数据结构以及put和get一,hashmap数据结构。数据结构中有数组和链表来实现对数据的存储,但是这两种方式的优点和缺点都很明显:1,数组存储,它的存储区间是连续的,比较占内存,故空间复杂度高。但是利用二分法进行查找的话,效率高,时间复杂度为O(1)。其特点就是:存储区间连续,查找速度快,但是占内存严重,插入和删除就慢。2,链表查询,它的存储区间离散,占内存比较宽松,故空间复杂度低,但时间复杂度高,为O(n)。其特

大家好,又见面了,我是你们的朋友全栈君。

一,hashmap数据结构。

数据结构中有数组和链表来实现对数据的存储,但是这两种方式的优点和缺点都很明显:
1,数组存储,它的存储区间是连续的,比较占内存,故空间复杂度高。但是利用二分法进行查找的话,效率高,时间复杂度为O(1)。其特点就是:存储区间连续,查找速度快,但是占内存严重,插入和删除就慢。
2,链表查询,它的存储区间离散,占内存比较宽松,故空间复杂度低,但时间复杂度高,为O(n)。其特点就是存储空间离散,空间复杂度低,插入和删除方便,但是时间复杂度高,导致查询比较慢。

综合以上两者的特点,就产生了一个时间复杂度低,占内存比较宽松,增删改查都比较方便的数据结构,也就是经常提到的哈希表。

哈希表最常用的实现方法就是拉链法,也可以理解为“链表的数组”。其模型大概如下图所示:
这里写图片描述

从上图中,比较容易看出,HashMap是Y轴方向是数组,X轴方向就是链表的存储方式。而每个数组的元素存储的都是链表的头结点。

那么这些元素是按照什么样的规则存储到数组中呢。一般情况是通过hash=index把链表和数组关联起来的,而hash=hash(key)%len获得,index就为数组的元素序列号,也就是元素的key的哈希值对数组长度取模得到。

这里写图片描述

比如上述长度为16的哈希表中,链表元素中其key的hash值为的12有:12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在index(数组下标)为12的位置。

二,Hashmap的存取实现

为什么说hashmap能随机进行存取呢?那是因为hashmap里有一个小小的算法,如下:

// 存储时:
int hash = key.hashCode(); // 这个hashCode方法这里不详述,只要理解每个key的hash是一个固定的int值
int index = hash % Entry[].length;
Entry[index] = value;

// 取值时:
int hash = key.hashCode();
int index = hash % Entry[].length;
return Entry[index];

1)put
在存储的时候,万一多个个元素的hash值(也就是hash(key)%Entry[].length)都等于同一个index,这样会不会导致后面一个元素覆盖掉前一个元素呢?答案是不会的。从上面的例子中就可以看出,hash=12的有四个元素在index=12的那一行。其实数组中存储的就是最后插入的元素,该元素的next值的就是之前的那个元素,并不是覆盖掉。

2)get
通过传入的key,先找到Y轴index为hash(key)%Entry[].length 的数组元素,然后再遍厉该元素所处的链表。

3)null key的存取
null key总是存放在Entry[]数组的第一个元素。

4)确定数组index:hashcode % table.length取模
HashMap存取时,都需要计算当前key应该对应Entry[]数组哪个元素,即计算数组下标;算法如下:

/**
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
return h & (length-1);
}

按位取并,作用上相当于取模mod或者取余%。
这意味着数组下标相同,并不表示hashCode相同。

5)再散列rehash过程
当哈希表的容量超过默认容量时,必须调整table的大小。当容量已经达到最大可能值时,那么该方法就将容量调整到Integer.MAX_VALUE返回,这时,需要创建一张新表,将原表的映射到新表中。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/144623.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python自动补全设置_python代码补全

    python自动补全设置_python代码补全Hello,大家好,我是橘子呀~前几期橘子给大家介绍了Python是什么以及如何安装Python软件。也分享了如何系统的以及高效率的去学习Python这门课程,还有一些避雷建议,今天橘子就分享给大伙一点宝藏干货!!!藏不住的东西,不如扬了它!请大家把它收入囊中~不要辜负我的一片苦心~一、Pycharm常用快捷键(Windows)Ctrl+Q快速查看文档Ctrl+鼠标左键简介及代码定义…

    2022年8月26日
    5
  • 使用astype实现dataframe字段类型转换

    使用astype实现dataframe字段类型转换在有些情况下,我们需要在DataFrame类型的数据中通过切片获得我们所需要的数据,然后转换为我们所需要的类型。Dataframe数据类型的转换需要用到astype函数。#encoding:utf-8importpandasaspddf=pd.DataFrame(pd.read_csv(‘film_log3.csv’,sep=’;’,encoding=’utf-8′,

    2022年5月12日
    47
  • Google Earth Engine学习笔记——介绍和入门

    Google Earth Engine学习笔记——介绍和入门   最近接触GoogleEarthEngine,觉得很好玩,也很有应用前景,关键是免费的地理计算云平台。所以想认真学习下,学习过程中作些小的总结和记录,资料来源均为网络或GoogleEarthEngineAPI指南,今天先讲讲入门的知识。1、GoogleEarthEngine介绍   GoogleEarthEngine是Google提供的对大量全球尺度地球科学资料(尤其是…

    2022年9月19日
    0
  • PyCharm 配置 Git

    PyCharm 配置 Gitwindows下step1: 首先安装GitHubstep2: 找到git.exe的路径git.exe的默认路径如下:C:\Users\yourname\AppData\Local\GitHub\PortableGit_69703d1db91577f4c666e767a6ca5ec50a48d243\bin\git.exestep3: Pych

    2022年8月29日
    0
  • 打印纸张尺寸换算_常用纸张尺寸大小对照表

    打印纸张尺寸换算_常用纸张尺寸大小对照表648A3297×420B3353×500C3324×458A4210×297B4250×353C4229×324A5148×210B5176×250C5162×229A6105×148B6125×176C6114×162A774×105B788×125C781×114A852×74B862×88DL110×220A937×52B944×62C7/681×162A1026×37B1031×44A组…

    2022年6月20日
    59
  • Opencv中width和widthStep的区别

    Opencv中width和widthStep的区别在Opencv的结构Iplimage中,widthStep并不一定等于width*nChannel*(数据类型所占字节),这是因为Opencv中对内存有管理的机制,这一机制会对内存进行对齐,也就是当每一行所占的字节数不等于4的倍数时会自动补齐。例如:width=117,depth=8U,nChannel=1,则widthStep=120,因为117不是4的倍数,所以补齐到120。如果dep

    2022年6月7日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号