HashMap详解
来源:互联网 发布:天津网络推广和seo 编辑:程序博客网 时间:2024/06/06 17:19
HashMap是一个数组链表结构,从源码中可以看出,每次新建一个HashMap时,都会初始化一个table数组。Table数组的元素为Entry节点。Entry为HashMap的内部类,它包含了键key、值value、下一个节点next,以及hash值。
Put源码:
public V put(K key, V value) { //当key为null,调用putForNullKey方法,保存null与table第一个位置中,这是HashMap允许为null的原因 if (key == null) return putForNullKey(value); //计算key的hash值 int hash = hash(key.hashCode()); ------(1) //计算key hash 值在 table 数组中的位置 int i = indexFor(hash, table.length); ------(2) //从i出开始迭代 e,找到 key 保存的位置 for (Entry<K, V> e = table[i]; e != null; e = e.next) { Object k; //判断该条链上是否有hash值相同的(key相同) //若存在相同,则直接覆盖value,返回旧value if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; //旧值 = 新值 e.value = value; e.recordAccess(this); return oldValue; //返回旧值 } } //修改次数增加1 modCount++; //将key、value添加至i位置处 addEntry(hash, key, value, i); return null; }
HashMap通过put(key,value)来存储,在put()方法的源码中,它的执行是:
1、 判断key==null,如果ky=null,则调用putForNullKey()方法,保存null在table第一个位置中,这是HashMap可以为null的原因。
2、 调用hashCode()方法计算key的hash值。
3、 调用indexFor()方法计算key hash值在table数组中的位置i。
4、 如果i位置没有元素则直接插入。
5、 否则开始迭代该处元素链表并依次比较其key和hash值。如果该链表上有相同的hash值,且key值也相同的话,则用新的Entry的value覆盖原来节点的value。但如果两个hash值相等但key不相等时,则将该节点插入链表的链头。具体的实现过程由addEntry()方法实现。
*indexFor():该方法中的h&(length-1), 就是相当于对length取模,它对取模速度比直接取模快得多;它还有一个重要的作用:均匀分布table数据和充分利用空间。
*扩容问题:当HashMap的元素越来越多时,碰撞的概率就会越来越大,那么链表的长度就会越来越长,这样势必会影响HashMap的速度。那为了保证HashMap的效率,系统就必须要在某个临界点进行扩容处理。但是扩容是一个非常耗时的操作过程,如果我们预知HashMap中元素的个数,可提供HashMap的性能。
下面讲一下读取实现:get(key)
通过key的hash值找到在table数组中的索引处的Entry,然后返回该key对应的value。具体:
源码:
public V get(Object key) { // 若为null,调用getForNullKey方法返回相对应的value if (key == null) return getForNullKey(); // 根据该 key 的 hashCode 值计算它的 hash 码 int hash = hash(key.hashCode()); // 取出 table 数组中指定索引处的值 for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; //若搜索的key与查找的key相同,则返回相对应的value if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }
1、 若key=null,调用getForNullKey()方法返回相应的value;
2、 根据key的hashCode值计算它的hash值;
3、 遍历table数组,首先判断它们的hash值是否相等,然后再判断它们的key值是否相等,如果相等的话,返回它的value值。
- HashMap 详解
- hashmap详解
- Hashmap详解
- HashMap详解
- HashMap详解
- HashMap详解
- HashMap 详解
- HashMap详解
- HashMap详解
- HashMap详解
- HashMap详解
- Hashmap详解
- HashMap详解
- HashMap详解
- HashMap详解
- hashmap详解
- HashMap详解
- HashMap详解
- hashMap的基础知识
- vtk编译vtkSDI找不到MFC模块的解决方案
- skynet添加动态库爬坑记录
- springboot 集成dubbo
- Android 开发之toolbar使用
- HashMap详解
- 队列
- Java--填充替换数组元素、对数组进行排序、复制数组、数组查询、
- java读取文本
- Beyond compare4.2.0Beta破解注册码 Beyond Compare:代码比较神器
- protege本体开发
- 【转载】字符编码详解——彻底理解掌握编码知识,“乱码”不复存在
- JVM监控与调优
- DB2 SQL Error: SQLCODE=-668, SQLSTATE=57016错误解决方法