结构:
jdk8之前是数组+链表(数据多之后存在大量hash冲突,链表会变得很长,查询速度太慢),jdk8之后数组+链表+红黑树。
key和value是整合为一个Entry单位存储的。
put过程:
- 通过hash算法计算key的hash值,并计算在数组下表index(下标 i = (n - 1) & hash)
- 如果index下标为空,直接存储
- 如果不空,则jdk8之前采用头插法,之后采用尾插法
- 返回当前节点对象
get过程
- 计算key的hash值,获取index的小标对象,
- 如果当前得到的对象不为空且key相等在返回当前对象的value,否则遍历链表,直到找到或已经找完为止。
使用红黑树原因
解决链表过长查询效率过低的问题,但是插入的速度会降低。使用阈值:数量达到8。
扩容过程
当HashMap中的元素越来越多的时候,碰撞的几率也就越来越高,所以为了提高查询的效率,就要对HashMap的数组进行扩容(与ArrayList类似)。当hashmap中的元素超过size*loadFactor时,就会把数组大小扩展为原来的两倍,并且重新计算每个元素在数组中的位置。
默认初始化时数组的大小是16,如果指定初始值,则初始化大小为与比传入的数比大的最近的2的n次方的数。
并发情况cpu100%(高并发下使用currententHashMap)
HashMap 导致 CPU 100% 的原因就是因为 HashMap 死循环导致的,大概就是并发情况下数据刚插进来,还没完成指针向后指的情况下又有新的数据插入。
标签:扩容,key,hash,HashMap,index,链表,数组,底层 From: https://www.cnblogs.com/habc706/p/16925465.html