hashMap的put,get分析

hashMap的put,get分析

每个java程序员都知道,HashMap是java中最重要的集合类之一,也是找工作面试中非常常见的考点,因为HashMap的实现本身确实蕴含了很多精妙的代码设计。

hashMap的put解析

  public V put(K var1, V var2) {
        return this.putVal(hash(var1), var1, var2, false, true);
    }

    final V putVal(int var1, K var2, V var3, boolean var4, boolean var5) {
        HashMap.Node[] var6 = this.table;//首先获取map当前的node的数组
        int var8;
        if (this.table == null || (var8 = var6.length) == 0) {
            var8 = (var6 = this.resize()).length;//判断当前node数组是否为空,如果为空的话,让其重新初始化,resize()方法
        }

        Object var7;
        int var9;
        if ((var7 = var6[var9 = var8 - 1 & var1]) == null) {
            var6[var9] = this.newNode(var1, var2, var3, (HashMap.Node)null);//根据传进来的key的hash值计算当前要put的值存在哪个node下面,如果为空则新建一个
        } else {
            Object var10;
            label79: {
                Object var11;
                if (((HashMap.Node)var7).hash == var1) {  //在上一个if里面var7已经复制查找到的不为空的node,如果查找的hash和想要put进来的k的hash相等
                    var11 = ((HashMap.Node)var7).key;//赋值var11位当前node的key
                    if (((HashMap.Node)var7).key == var2 || var2 != null && var2.equals(var11)) {//判断node的key和所要插进来的key是否相等
                        var10 = var7;//将当前的 node赋值var10
                        break label79;
                    }
                }

                if (var7 instanceof HashMap.TreeNode) {//判断查找到的node如果已经是红黑数的时候
                    var10 = ((HashMap.TreeNode)var7).putTreeVal(this, var6, var1, var2, var3);//添加当前的值到数里面
                } else {
                    int var12 = 0;

                    while(true) {//在这里用了个循环
                        var10 = ((HashMap.Node)var7).next;//在上面判断并且计算出要插入的值得key的hash要存的node下面,因为是链表结构,所以当以上情况都没有精要
                                                            //在当前的node下加入
                        if (((HashMap.Node)var7).next == null) {//如果下一个为null
                            ((HashMap.Node)var7).next = this.newNode(var1, var2, var3, (HashMap.Node)null);//在当前链表下新加
                            if (var12 >= 7) {//判断当前链表的长度是否已经大于7
                                this.treeifyBin(var6, var1);//存成数结构
                            }
                            break;
                        }

                        if (((HashMap.Node)var10).hash == var1) {//如果当前的node的key相等
                            var11 = ((HashMap.Node)var10).key;
                            if (((HashMap.Node)var10).key == var2 || var2 != null && var2.equals(var11)) {
                                break;
                            }
                        }

                        var7 = var10;//如果以上情况都不存在,继续寻找下一个
                        ++var12;//累计连边的长度
                    }
                }
            }

            if (var10 != null) {//最后判断var10是否为空,如果不为空则在map里面已经存在和要存的值key相等,然后用新的value覆盖旧的
                Object var13 = ((HashMap.Node)var10).value;
                if (!var4 || var13 == null) {
                    ((HashMap.Node)var10).value = var3;
                }

                this.afterNodeAccess((HashMap.Node)var10);
                return var13;
            }
        }

        ++this.modCount;
        if (++this.size > this.threshold) {
            this.resize();
        }

        this.afterNodeInsertion(var5);
        return null;
    }

接下来就是get方法了

  public V get(Object var1) {
        HashMap.Node var2;
        return (var2 = this.getNode(hash(var1), var1)) == null ? null : var2.value;
    }

    final HashMap.Node getNode(int var1, Object var2) {
        HashMap.Node[] var3 = this.table;//获取当前node数组
        HashMap.Node var4;
        int var6;
        if (this.table != null && (var6 = var3.length) > 0 && (var4 = var3[var6 - 1 & var1]) != null) {//判断数组不为空,并且获取到的hash存在的链表节点不为空
            Object var7;
            if (var4.hash == var1) {//如果就在当前链表的node和要查的key相等,直接返回房钱的node
                var7 = var4.key;
                if (var4.key == var2 || var2 != null && var2.equals(var7)) {
                    return var4;
                }
            }

            HashMap.Node var5 = var4.next;//获取链表的下一个
            if (var4.next != null) {
                if (var4 instanceof HashMap.TreeNode) {//判断查到的是数结构的话,去查询红黑树
                    return ((HashMap.TreeNode)var4).getTreeNode(var1, var2);
                }

                do {//循环依次在当前的链表下查找,如果没有就返回null
                    if (var5.hash == var1) {
                        var7 = var5.key;
                        if (var5.key == var2 || var2 != null && var2.equals(var7)) {
                            return var5;
                        }
                    }
                } while((var5 = var5.next) != null);
            }
        }

        return null;

总结

在源码里,我们可以看到里面一些put,get的方法都是调用自身的final心事的方法,里面的含义除了不被允许修改外应该还有其他一些含义,,,,,
而且在里面一些变量的复制都是在if或者fou里面直接赋值,没有一丝多余,干净,只不过看的让热头晕,,,

你可能感兴趣的:(hashMap的put,get分析)