




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【达内java培训】Java中HashMap的工作机制现在很多的Java程序员都会把HashMap当作一个热门话题,今天我也来说一说Hashmap。我假设你对HashMap感兴趣,另外我认为你已经了解了HashMap的基础,这里我就不再赘述HashMap是个什么东东,如果对于你来讲HashMap还是一个新概念的话,你可以去看看官方的javadoc.目录: 1、一句话回答2、什么是哈希3、关于Entry类的一点介绍4、put()方法实际上做了什么5、get()方法内部工作机制6、注意点一句话回答 如果任何人让我描述一下HashMap的工作机制的话,我就简单的回答:“基于Hash的规则”。这句话非常简单,但是要理解这句话之前,首先我们得了解什么是哈希,不是么?什么是哈希 哈希简单的说就是对变量/对象的属性应用某种算法后得到的一个唯一的串,用这个串来确定变量/对象的唯一性。一个正确的哈希函数必须遵守这个准则。当哈希函数应用在相同的对象或者equal的对象的时候,每次执行都应该返回相同的值。换句话说,两个相等的对象应该有相同的hashcode。注:所有Java对象都从Object类继承了一个默认的hashCode()方法。这个方法将对象在内存中的地址作为整数返回,这是一个很好的hash实现,他确保了不同的对象拥有不同的hashcode。关于Entry类的一点介绍 一个map的定义是:一个映射键(key)到值(value)的对象。非常简单对吧。所以,在HashMap中一定有一定的机制来存储这些键值对。使得,HashMap有一个内部类Entry,看起来像这样。 static class Entry implements Map.Entry final K key; V value; Entry next; final int hash; ./More code goes here 当然,Entry类有属性用来存储键值对映射。key被final标记,除了key和value,我们还能看到两个变量next和hash。接下来我们试着理解这些变量的含义。put()方法实际上做了什么 再进一步看put方法的实现之前,我们有必要看一看Entry实例在数组中的存储,HashMap中是这样定义的: /* * The table, resized as necessary. Length MUST Always be a power of two. */ transient Entry table; 现在再来看put方法的实现。 /* * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, the old * value is replaced. * * param key key with which the specified value is to be associated * param value value to be associated with the specified key * return the previous value associated with key, or * null if there was no mapping for key. * (A null return can also indicate that the map * previously associated null with key.) */ public V put(K key, V value) if (key = null) return putForNullKey(value); int hash = hash(key.hashCode(); int i = indexFor(hash, table.length); for (Entry e = tablei; e != null; e = e.next) Object k; 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; 让我们一步一步的看 首先,检查key是否为null,如果key是null值被存在table0的位置,因为null的hashcode始终为0接下来,通过key的hashCode()方法计算了这个key的hash值,这个hash值被用来计算存储Entry对象的数组中的位置。JDK的设计者假设会有一些人可能写出非常差的hashCode()方法,会出现一些非常大或者非常小的hash值。为了解决这个问题,他们引入了另外一个hash函数,接受对象的hashCode(),并转换到适合数组的容量大小。接着是indexFor(hash,table,length)方法,这个方法计算了entry对象存储的准确位置。接下来就是主要的部分,我们都知道两个不相等的对象可能拥有过相同的hashCode值,两个不同的对象是怎么存储在相同的位置叫做bucket呢?答案是LinkedList。如果你记得,Entry类有一个next变量,这个变量总是指向链中的下一个变量,这完全符合链表的特点。所以,在发生碰撞的时候,entry对象会被以链表的形式存储起来,当一个Entry对象需要被存储的时候,hashmap检查该位置是否已近有了一个entry对象,如果没有就存在那里,如果有了就检查她的next属性,如果是空,当前的entry对象就作为已经存储的entry对象的下一个节点,依次类推。如果我们给已经存在的key存入另一个value会怎么样的?逻辑上,旧的值将被替换掉。在检测了Entry对象的存储位置后,hashmap将会遍历那个位置的entry链表,对每一个entry调用equals方法,这个链表中的所有对象都具有相同的hashCode()而equals方法都不等。如果发现equals方法有相等的就执行替换。在这种方式下HashMap就能保证key的唯一性。get方法的工作机制 现在我们已经了解了HashMap中存储键值对的机制。下一个问题是:怎样从一个HashMap中查询结果。其实逻辑跟put是一样的,如果传入的key有匹配就将该位置的value返回,如果没有就返回null. /* * Returns the value to which the specified key is mapped, * or code null if this map contains no mapping for the key. * * More formally, if this map contains a mapping from a key * code k to a value code v such that code (key=null ? k=null : * key.equals(k), then this method returns code v; otherwise * it returns code null. (There can be at most one such mapping.) * * A return value of code null does not necessarily * indicate that the map contains no mapping for the key; its also * possible that the map explicitly maps the key to code null. * The link #containsKey containsKey operation may be used to * distinguish these two cases. * * see #put(Object, Object) */ public V get(Object key) if (key = null) return getForNullKey(); int hash = hash(key.hashCode(); for (Entry e = tableindexFor(hash, table.length); e != null; e = e.next) Object k; if (e.hash = hash & (k = e.key) = key | key.equals(k) return e.value; return null; 上面的代码看起来跟put()方法很像,除了if (e.hash = hash & (k = e.key) = key | key.equals(k)。注意点 存储Entry对象的数据结构是一个叫做Entry类型的table数组。数组中一个特定的索引位置称为bucket,因为它可以容纳一个LinkedList的第一个元素的对象。Key对象的hashCode()需要用来计算Entry对象的存储位置。Key对象的equals()方法需要用来维持Map中对象的唯一性。get()和put()方法跟Value对象的hashCode和equals方法无关。null的hashCode总是0,这样的Entry对象总是被存储在数组的第一个位置成都java培训
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年教师招聘之《小学教师招聘》考前冲刺练习题含答案详解【能力提升】
- 押题宝典教师招聘之《小学教师招聘》题库及1套参考答案详解
- 教师招聘之《小学教师招聘》题型+答案(考点题)附答案详解(夺分金卷)
- 押题宝典教师招聘之《小学教师招聘》模考模拟试题含答案详解ab卷
- 演出经纪人之《演出经纪实务》考前冲刺分析附参考答案详解(综合卷)
- 押题宝典教师招聘之《小学教师招聘》题库及一套参考答案详解
- 2025年江苏银行招聘考试(英语)历年参考题库含答案详解
- 2025昆明卫生职业学院第三批云南省产业导师选聘工作(10人)笔试备考题库及答案解析
- 节能理念解读课件
- 【中考真题】2025年辽宁省中考生物学试卷(含答案)
- 第二单元混合运算单元测试卷(含答案) 2025-2026学年人教版三年级数学上册
- 出境人员行前安全培训课件
- 短视频个人劳务合同范本
- 纯电动汽车维护与保养 课件 模块一新能源汽车维护与保养基础认知
- 翻译后的基因表达调控
- 《心系国防 强国有我》 课件-2024-2025学年高一上学期开学第一课国防教育主题班会
- AS9100D体系标准中文版
- 中国铁塔-基站规范培训课件
- GB-T 41378-2022 塑料 液态食品包装用吹塑聚丙烯容器(高清版)
- 上海证券交易所公司债券预审核指南(三)审核和发行程序及其实施
- 食管癌颈部吻合ppt课件
评论
0/150
提交评论