Java中HashMap实现原理浅析
来源:互联网 发布:小儿常见病推拿软件 编辑:程序博客网 时间:2024/04/24 08:01
概述
HashMap是基于Map接口的实现。这个实现提供了所有可选的映射操作,并且允许null值和null键。(除了不同步和允许空值以外,HashMap和Hashtable几乎等价)。这个类不保证映射之间的顺序;尤其是,它不保证随着时间的推移映射顺序不变(翻译自Java API文档)。
哈希表是一个“链表散列”的结构,是由数组和链表结合而成。
HashMap的基层是一个数组结构,而数组中的每一项又可以拓展成为一个链表。具体的实现形式Entry就是数组中的元素,它是由key和value组成的基本单元,其本身持有Entry的引用来构成链表形式。
基本方法实现
此处源码版本为JDK1.7。
put方法
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; 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值,并由此得出它在数组中的index值,判断是否已有key存在,若已在则覆盖;若不存在则将新元素加到链表后,加元素操作具体由addEntry方法实现。
在addEntry方法中包含有扩容判断和createEntry方法,createEntry方法将新创建的 Entry 放入 bucketIndex 索引处,并让这个新的 Entry 指向原来的 Entry。
get方法
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
get方法中用getEntry来判断key值在原数组中是否已存在并做取值操作。
总体来说,HashMap的底层是用Entry数组来实现的,通过key的哈希函数来寻找指定的key-value对位置并进行操作。
HashMap的refresh操作
当HashMap中的元素个数超过数组大小乘以负载因子时,就需要对HashMap进行扩容,类似的操作在List中也有。
void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
transfer(newTable, initHashSeedAsNeeded(newCapacity));
table = newTable;
threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}
新建Entry数组后将原数组中的元素转移到新数组中,即重新计算它们在新数组中的位置。默认的负载因子是0.75,扩容规模为原来的2倍。
以上为对HashMap实现的基本理解,更详细的内容参考http://zhangshixi.iteye.com/blog/672697
- Java中HashMap实现原理浅析
- 浅析Java中HashMap的底层原理
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- hashmap实现原理浅析
- java中HashMap实现原理
- 【翻译】Java中HashMap的工作原理浅析
- Java中HashMap的实现原理
- java中Hashmap的实现原理
- java中Hashmap的实现原理
- java中Hashmap的实现原理
- Java中HashMap的实现原理
- Java中HashMap实现原理初探
- 【BZOJ】【P2986】【Non-Squarefree Numbers】【题解】【数论】
- ssi中struts,spring、iBATIS各自作用
- 什么是编程语言????
- 【Spring】Spring学习笔记-01-入门级实例
- 黑马程序员-----Java学习笔记之基础篇(一)
- Java中HashMap实现原理浅析
- Linux下/proc目录简介
- MySQL运行状态show status中文详解
- 如何查询出ORACLE表的列的值是中文的
- Unity 3D-- 摄像机Clear Flags和Culling Mask属性用途详解
- 关于C#中dataGridView常用的功能(一)
- loadrunner 测试下载文件的测试脚本
- Android之ListView列表视图和界面跳转实现
- 有一个定期写博客的习惯,必将使程序员收益终身