欢迎来到天天文库
浏览记录
ID:30777520
大小:273.92 KB
页数:16页
时间:2019-01-03
《javahashset和hashmap源码剖析-编程开发技术》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、JavaHashSct和HashMap源码剖析-编程开发技术JavaHashSet和HashMap源码剖析原文出处:CarpenterLee总体介绍之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说血s力Se方里面有一个朋(适配器模式)。因此本文将重点分析HashMap.HashMap实现了疑如接口,允许放入mill元索,除该类未实现同步外,其余跟Ilashtablc大致相同,跟如不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元
2、素的顺序也会被重新打散,因此不同时间迭代同一个HashMap的顺序可能会不同。根据对冲突的处理方式不同,哈希表有两种实现方式,一种开放地址方式(Openaddressing),另一种是冲突链表方式(Separatechainingwithlinkedlists)。Java?屁sAtfep采用的是冲突链表方式oEntryvK,V>[]tableHashMap纟吉buckets0X1■■2■■3X4■■5X6X7■■muedeukey
3、value•key
4、valueX左〉右!口汁做Tkey
5、value•key
6、valu
7、eX从上图容易看出,如果选择合适的哈希函数,put()和gct()方法可以在常数时间内完成。但在对/fes加彻7进行迭代时,需耍遍历整个table以及后而跟的冲突链表。因此对于迭代比较频繁的场景,不宜将血3加血的初始大小设的过大。有两个参数可以影响HashMap的性能:初始容量(inilalcapacity)和负载系数(loadfactor)o初始容量指定了初始table的大小,负载系数用來指定自动扩容的临界值。当entry的数量超iicapacity*loadfactor吋,容器将自动扩容并重新哈希。对于插入元索较多的
8、场景,将初始容量设大可以减少重新哈希的次数。将对向放入到HashMap或Zfes力SeZ■屮II寸,有两个方法需要特别关心:hashCode()和equals()ohashCode0方法决定了对象会被放到哪个bucket里,当多个对象的哈希值冲突时,equals()方法决定了这些对象是否是“同一个对象”。所以,如果耍将自定义的对象放入到HashMap或HashSet屮,需要@Override?hashCode()和equals()方法。方法剖析get0get(Objectkey)方法根据指定的key值返冋对应的value,
9、该方法调用了getEntry(Objectkey)得到相应的entry,然后返冋entry.getValueO。因此getEntry()是算法的核心。算法思想是首先通过heishO函数得到对应bucket的卜•标,然后依次遍历冲突链表,通过key.equals(k)方法来判断是否是要找的那个entry。从上图容易看出,如果选择合适的哈希函数,put()和gct()方法可以在常数时间内完成。但在对/fes加彻7进行迭代时,需耍遍历整个table以及后而跟的冲突链表。因此对于迭代比较频繁的场景,不宜将血3加血的初始大小设的过大
10、。有两个参数可以影响HashMap的性能:初始容量(inilalcapacity)和负载系数(loadfactor)o初始容量指定了初始table的大小,负载系数用來指定自动扩容的临界值。当entry的数量超iicapacity*loadfactor吋,容器将自动扩容并重新哈希。对于插入元索较多的场景,将初始容量设大可以减少重新哈希的次数。将对向放入到HashMap或Zfes力SeZ■屮II寸,有两个方法需要特别关心:hashCode()和equals()ohashCode0方法决定了对象会被放到哪个bucket里,当多个
11、对象的哈希值冲突时,equals()方法决定了这些对象是否是“同一个对象”。所以,如果耍将自定义的对象放入到HashMap或HashSet屮,需要@Override?hashCode()和equals()方法。方法剖析get0get(Objectkey)方法根据指定的key值返冋对应的value,该方法调用了getEntry(Objectkey)得到相应的entry,然后返冋entry.getValueO。因此getEntry()是算法的核心。算法思想是首先通过heishO函数得到对应bucket的卜•标,然后依次遍历冲突
12、链表,通过key.equals(k)方法来判断是否是要找的那个entry。上图中hash(k)&(table,length-1)等价于hash(k)%table.length,原因是HashMap要求table,length必须是2的指数,因此table,length-1就是二进制低位全是1,跟hash
此文档下载收益归作者所有