👌jdk8的hashmap的put过程?
题目详细答案
put方法的实现
1 | public V put(K key, V value) { |
put方法调用了putVal方法。这里的hash(key)是计算键的哈希值。
计算哈希值
hash方法用于计算键的哈希值并进行扰动处理,以减少冲突。
1 | static final int hash(Object key) { |
putVal方法的实现
putVal方法是HashMap中实际执行插入操作的核心方法。
1 | final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { |
详细步骤解析
- 初始化表:如果哈希表还没有初始化或长度为0,则进行初始化(扩容)。
1 | if ((tab = table) == null || (n = tab.length) == 0) |
- 计算索引:通过哈希值和数组长度计算出索引位置。
1 | if ((p = tab[i = (n - 1) & hash]) == null) |
- 插入新节点:如果索引位置为空,直接插入新节点。
- 处理哈希冲突:如果索引位置不为空,需要处理冲突。
检查是否存在相同的键:如果找到相同的键,替换其值。
红黑树处理:如果当前节点是红黑树节点,则调用putTreeVal方法插入。
链表处理:如果当前节点是链表节点,遍历链表插入新节点。
- 转换为红黑树:如果链表长度超过阈值(8)且数组长度大于 64,则将链表转换为红黑树。
1 | if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st |
- 更新节点值:如果存在相同的键,更新其值。
1 | if (e != null) { // existing mapping for key |
- 调整大小:插入新节点后,增加元素数量。如果超过阈值,则进行扩容。
1 | ++modCount;if (++size > threshold) |
- 插入后的处理:进行一些插入后的处理操作。
1 | afterNodeInsertion(evict); |
/cvh030rky8ki5bhi>