JDK源码(二十三):HashMap
Posted jdkSpring
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK源码(二十三):HashMap相关的知识,希望对你有一定的参考价值。
哈希表
哈希冲突
解决冲突的一般办法
再哈希法:首先定义很多hash函数,当发生哈希冲突时,就再使用另一个hash函数计算另一个哈希值,直到不冲突为止。
类名
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
变量(部分)
方法(JDK1.8)
put(K key, V value)
对key的hashCode()做hash,然后再计算index;
如果没碰撞直接放到bucket里;
如果碰撞了,以链表的形式存在buckets后;
如果碰撞导致链表过长(大于等于TREEIFY_THRESHOLD),就把链表转换成红黑树;
如果节点已经存在就替换old value(保证key的唯一性)
如果bucket满了(超过load factor*current capacity),就要resize。
在jdk1.8版本后,java对HashMap做了改进,在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度。关于红黑树,读者可另行查看,太烧脑了。
resize()
初始化或加倍表大小。如果为空,则根据字段阈值中保留的初始容量目标进行分配。然而又因为我们使用的是2次幂的扩展(指长度扩为原来2倍),所以,元素的位置要么是在原位置,要么是在原位置再移动2次幂的位置。
get(Object key)
bucket里的第一个节点,直接命中;
如果有冲突,则通过key.equals(k)去查找对应的entry,若为树,则在树中通过key.equals(k)查找;若为链表,则在链表中通过key.equals(k)查找。
HashMap实现多线程
Map map = Collections.synchronizedMap(new HashMap<>());
以上是关于JDK源码(二十三):HashMap的主要内容,如果未能解决你的问题,请参考以下文章