- 1、本文档共8页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
HashMap的数据结构剖析
1. HashMap的数据结构
数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。
????? 数组
数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;
链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。
那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表。哈希表((Hash table)既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。
从上图我们可以发现哈希表是由数组+链表组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。那么这些元素是按照什么样的规则存储到数组中呢。一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。
HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。这可能让我们很不解,一个线性的数组怎么实现按键值对来存取数据呢?这里HashMap有做一些处理。
首先HashMap里面实现一个静态内部类Entry,其重要的属性有?key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。
????/**
?????*?The?table,?resized?as?necessary.?Length?MUST?Always?be?a?power?of?two.
?????*/
????transient?Entry[]?table;
2. 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];
?public?V?put(K?key,?V?value)?{
????????if?(key?==?null)
????????????return?putForNullKey(value);?//null总是放在数组的第一个链表中????????int?hash?=?hash(key.hashCode());
????????int?i?=?indexFor(hash,?table.length);
????????//遍历链表????????for?(EntryK,V?e?=?table[i];?e?!=?null;?e?=?e.next)?{
????????????Object?k;
????????????//如果key在链表中已存在,则替换为新value????????????if?(e.hash?==?hash??((k?=?e.key)?==?key?||?key.equals(k)))?{
????????????????V?oldValue?=?e.value;
????????????????e.value?=?value;
????????????????e.recordAccess(this);
????????????????return?oldValue;
????????????}
????????}
????????modCount++;
????????addEntry(hash,?key,?value,?i);
????????return?null;
????}
?
void?addEntry(int?hash,?K?key,?V?value,?int?bucketIndex)?{
????EntryK,V?e?=?table[bucketIndex];
????table[bucketIndex]?=?new?EntryK,V(hash,?key,?value,?
您可能关注的文档
- 第3章长度测量技术基础.ppt
- GYK综合测试台软件说明.doc
- GZ-038“计算机网络应用”赛项规程(高职组).doc
- G专题二阴影部分图形的有关计算(赛课).ppt
- g江苏省连云港市2015-2016学年高二上学期期末质量检测化学试题(选修)Word版含答案.doc
- 第3节电磁感应定律的应用.1.ppt
- 第3节物质的量浓度实用CB4.ppt
- 第3节社会行为.ppt
- G电子技术基础-第11章_时序逻辑电路.ppt
- H108新.ppt
- 2023年铜陵市公务员考试行测试卷历年真题带答案详解.docx
- 2024民航职业技能鉴定模拟题库附完整答案详解(各地真题).docx
- 2024教育硕士经典例题带答案详解(培优B卷).docx
- 2024广播影视职业技能鉴定过关检测试卷【真题汇编】附答案详解.docx
- 2024民航职业技能鉴定检测卷附答案详解【综合题】.docx
- 2024教育硕士考试彩蛋押题含完整答案详解(考点梳理).docx
- 2024教育硕士考前冲刺测试卷含答案详解【夺分金卷】.docx
- 2024教育硕士高频难、易错点题(有一套)附答案详解.docx
- 2024教育硕士能力检测试卷【名师系列】附答案详解.docx
- 2024民航职业技能鉴定常考点试卷含答案详解(突破训练).docx
文档评论(0)