前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >源码分析HashMap之putVal

源码分析HashMap之putVal

作者头像
九转成圣
发布2024-04-10 16:46:52
580
发布2024-04-10 16:46:52
举报
文章被收录于专栏:csdncsdn
代码语言:javascript
复制
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {
### 标签:源码|集合

    HashMap.Node<K, V>[] tab;
    HashMap.Node<K, V> p;
    int n, i;
    // 初始化table
    if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
    /**
     * hash桶里还没有元素
     * 为什么是(n - 1)不是n与hash&运算
     * 因为&一边为1或者连续的1时,&运算的结果与&另一边的相等
     * 1&0=0 0&1=0 1&1=1
     */
    if ((p = tab[i = (n - 1) & hash]) == null)
        tab[i] = newNode(hash, key, value, null);
    // hash桶中已经存在元素了
    else {
        HashMap.Node<K, V> e;
        K k;
        // key相同做覆盖操作
        if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        else if (p instanceof HashMap.TreeNode)
            e = ((HashMap.TreeNode<K, V>) p).putTreeVal(this, tab, hash, key, value);
        else {
            // 两种情况退出for循环 1.到了链表的末尾 2.找到了相同的key
            for (int binCount = 0; ; ++binCount) {
                // 1.到了链表的末尾
                if ((e = p.next) == null) {
                    // 在遍历链表的时候才加入新节点,也就是说新节点在不在遍历的范围内
                    p.next = newNode(hash, key, value, null);
                    // 链表长度 = binCount+1(binCount从0开始)+1(新增的节点)
                    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                        //添加第九个元素的时候走到了这里(9个元素hash相同),即链表长度大于8
                        treeifyBin(tab, hash);
                    break;
                }
                // 2.找到了相同的key
                if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                p = e;
            }
        }
        // 找到了相同的key put做覆盖操作
        if (e != null) { // existing mapping for key
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            afterNodeAccess(e);
            return oldValue;
        }
    }
    ++modCount;
    // 因为size 是从0 开始的,所以++size代表了添加完当前元素后的数量 第一次扩容是在添加第13个元素的时候(不考虑初始化扩容和聊表长度超过8但table.length<64的情况)
    if (++size > threshold)
        resize();
    afterNodeInsertion(evict);
    return null;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档