HashMap实现原理
来源:互联网 发布:南京高新沿江网络问政 编辑:程序博客网 时间:2024/06/15 22:17
HashMap数据结构
在对hash表有一定了解的基础上,分析java中的HashMap。
JDK1.6中的hash函数
static int hash(int paramInt)//paramInt:键的hashCode { paramInt ^= paramInt >>> 20 ^ paramInt >>> 12; return paramInt ^ paramInt >>> 7 ^ paramInt >>> 4; } static int indexFor(int paramInt1, int paramInt2) { return paramInt1 & paramInt2 - 1; } int i = hash(paramK.hashCode()); int j = indexFor(i, this.table.length);
JDK1.7中的hash函数
final int hash(Object paramObject)//paramObject:键 { int i = this.hashSeed; if ((0 != i) && ((paramObject instanceof String))) { return Hashing.stringHash32((String)paramObject); } i ^= paramObject.hashCode(); i ^= i >>> 20 ^ i >>> 12; return i ^ i >>> 7 ^ i >>> 4; } static int indexFor(int paramInt1, int paramInt2) { return paramInt1 & paramInt2 - 1; } int i = hash(paramK); int j = indexFor(i, this.table.length);
hash()函数的核心:
int hashCode;hashCode^= hashCode>>> 20 ^ hashCode>>> 12;int hash =hashCode^ hashCode>>> 7 ^ hashCode>>> 4;
hash()函数举例:
- 十进制数32768(二进制1000 0000 0000 0000),运算结果是35080(二进制1000 1001 0000 1000)
- 十进制数61440(二进制1111 0000 0000 0000),运算结果是65263(二进制1111 1110 1110 1111)
hash()算法使得hash()函数的目的是将“1”变得均匀一点,然后与HashMap的承载量length进行逻辑与运算,即(hash&length-1)这样得到的结果是一个比length小的正数,即index。
这种算法使得最低位上原hashCode的8位都参与了^运算,所以在table.length为默认值16的情况下面,hashCode任意位的变化基本都能反应到最终hash table 定位算法中,这种情况下只有原hashCode第3位高1位变化不会反应到结果中,即:0x7FFFF7FF的i=15。达到了散列的本意:尽量均匀。
处理冲突方法
- 开放定址法
- 再哈希法
- 连地址法
Java中hashmap解决冲突的办法就是链地址法。
HashMap里面实现 了一个静态内部类Entry,其重要的属性有三个:key、value、next。
static class Entry<K, V> implements Map.Entry<K, V>{ final K key; V value; Entry<K, V> next; int hash;}
由此看出,HashMap的基础是一个Entry[]。
HashMap的put过程
public V put(K paramK, V paramV) { if (this.table == EMPTY_TABLE) { inflateTable(this.threshold); } if (paramK == null)//null总是放在数组的第一个位置 return putForNullKey(paramV); int i = hash(paramK); int j = indexFor(i, this.table.length); for (Entry localEntry = this.table[j]; localEntry != null; localEntry = localEntry.next) {//遍历链表 Object localObject1; if ((localEntry.hash == i) && (((localObject1 = localEntry.key) == paramK) || (paramK.equals(localObject1)))) {//如果key在链表中已存在,则替换为新value Object localObject2 = localEntry.value; localEntry.value = paramV; localEntry.recordAccess(this); return localObject2; } } this.modCount += 1; addEntry(i, paramK, paramV, j); return null; } void addEntry(int paramInt1, K paramK, V paramV, int paramInt2) { if ((this.size >= this.threshold) && (null != this.table[paramInt2])) { //如果size超过threshold,则扩充table大小。再散列 resize(2 * this.table.length); paramInt1 = null != paramK ? hash(paramK) : 0; paramInt2 = indexFor(paramInt1, this.table.length); } createEntry(paramInt1, paramK, paramV, paramInt2); }
- 初始化HashMap为空
- 第一个键值对A进来,通过计算其key得到index=0,记做:Entry[0]=A
- 第二个键值对B进来,通过计算其key得到index=0,Entry[0]里已经有数据,执行B.next=A,Entry[0]=B
- 第三个键值对C进来,通过计算其key得到index=0,Entry[0]中是B,执行C.next=B,Entry[0]=C
即:数组中永远存放的是最后插入的元素。
再散列rehash过程
HashMap的大小
0 0
- HashMap的实现原理
- Java HashMap实现原理
- HashMap的实现原理
- hashMap的实现原理
- HashMap的实现原理
- HashMap的实现原理
- Hashmap实现原理
- HashMap的实现原理
- Hashmap实现原理
- HashMap的实现原理
- HashMap的实现原理
- HashMap的实现原理
- HashMap的实现原理
- HashMap实现原理
- HashMap的实现原理
- Hashmap实现原理
- HashMap的实现原理
- Java HashMap实现原理
- 新版手机号码正则表达式
- Android二维码开发(基于Zxing)
- Reflector、reflexil、De4Dot、IL指令速查表
- HDU 2544(最短路径 SPFA 算法模板)
- VC使用动态库关于/MD与/MT的一个坑
- HashMap实现原理
- 2016多校联合训练赛 第四场1001 Another Meaning hdu 5763
- eclipse混淆打包规则
- 在VC中使用自定义资源,FindResource,LoadResource,LockResource
- 利用多线程进行多客户端通信
- ASCII表
- 阿里15年前端实习笔试-自己尝试做的答案
- 102. Binary Tree Level Order Traversal
- HDU 1181 变形课 (DFS)