阅读android-27源码HashMap篇

啥都不会就翻译下代码吧

  1. 先分析HashMap的get方法
  2. 先查看get方法体
 public V get(Object key) {
        Node<K,V> e;
        return (e = getNode(hash(key), key)) == null ? null : e.value;
    }

3.在查看getNode方法体 我看代码注释 水平有限仅供参考

 final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            //1、判斷 table數組是否為空
            //2、判斷 table的長度大於0
            //3、判斷 0至table,length-1與hash值後的數組地址 一般來說是鏈錶頭或者是樹的頂部不為空
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                //判斷鏈錶或者樹的第一個數是否就是要找的結果如果是直接輸出
                return first;
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    //如果是樹則找到樹頂端遍歷查找樹
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {
                    //如果是鏈錶則遍歷鏈錶找出對應的值
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }
        return null;
    }
  1. 接下来看((TreeNode<K,V>)first).getTreeNode(hash, key)的方法体
   /**
         * Calls find for root node.
         */
        final TreeNode<K,V> getTreeNode(int h, Object k) {
            return ((parent != null) ? root() : this).find(h, k, null);
        }

其中root方法去找了树顶 并返回了值

  final TreeNode<K,V> root() {
    for (TreeNode<K,V> r = this, p;;) {
        if ((p = r.parent) == null)
            return r;
        r = p;
    }
}
  1. 查看find方法 盲猜是遍历树然后找到符合的key的TreeNode返回
 /**
 * Finds the node starting at root p with the given hash and key.
 * The kc argument caches comparableClassFor(key) upon first use
 * comparing keys.
 */
final TreeNode<K,V> find(int h, Object k, Class<?> kc) {
    TreeNode<K,V> p = this;
    do {
        int ph, dir; K pk;
        TreeNode<K,V> pl = p.left, pr = p.right, q;
        if ((ph = p.hash) > h)
            //1、ph 賦值為當前P的hash值
            //2、如果大於輸入的hash值 則p賦值為樹的左葉 從樹左邊開始找
            p = pl;
        else if (ph < h)
            //1、如果小於輸入的hash值 則p賦值為樹的右葉 從樹右邊開始找
            p = pr;
        else if ((pk = p.key) == k || (k != null && k.equals(pk)))
            //pk賦值為p.key
            //如果當前p的key相等於輸入k 或者是 k不為空並且k與當前p.key的equal方法成立就是找到了值返回p即可
            //這裡有個疑惑k是Object的equal方法還是泛型類K的equals方法
            return p;
        else if (pl == null)
            //如果左邊沒有值 找右邊的值
            p = pr;
        else if (pr == null)
            //如果右邊沒有值  找左邊的值
            p = pl;
        else if ((kc != null ||
                  (kc = comparableClassFor(k)) != null) &&
                 (dir = compareComparables(kc, k, pk)) != 0)
            //kc是null
            //只有当传入对象的运行时类型符合”class C implements Comparable”这个条件时,返回对象的运行时类型,否则返回null。
            //假設key是String 其實實現了這個接口 然後返回一個String.class
            //如果pk不為空 並且 pk.getClass()等於kc(String.class) 然後返回k和pk的compareTo結果賦值給dir
            //如果上述條件不成立不進來這裡
            p = (dir < 0) ? pl : pr;//如果dir小於0則左邊繼續 否則右邊繼續(右邊有個0的情況)
        else if ((q = pr.find(h, k, kc)) != null)
            //右邊樹葉繼續找 
            return q;
        else
            //到這裡我已經混亂了 什麼情況會出現這裡
            //如果以上條件都不滿足默認去左邊找
            p = pl;
    } while (p != null);
    //沒找到返回空
    return null;
}

这里要把引用的地址贴一下 这一段是别人的生产结果我也是引用一下

 static Class<?> comparableClassFor(Object x) {
        if (x instanceof Comparable) {  // 判断是否实现了Comparable接口
            Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
            if ((c = x.getClass()) == String.class) 
                return c;   // 如果是String类型,直接返回String.class
            if ((ts = c.getGenericInterfaces()) != null) {  // 判断是否有直接实现的接口
                for (int i = 0; i < ts.length; ++i) {   // 遍历直接实现的接口
                    if (((t = ts[i]) instanceof ParameterizedType) &&   // 该接口实现了泛型
                        ((p = (ParameterizedType)t).getRawType() == // 获取接口不带参数部分的类型对象
                         Comparable.class) &&   //  该类型是Comparable
                        (as = p.getActualTypeArguments()) != null &&    // 获取泛型参数数组
                        as.length == 1 && as[0] == c)   // 只有一个泛型参数,且该实现类型是该类型本身
                        return c;   // 返回该类型
                }
            }
        }
        return null;

get方法就分析到这里仅仅把看到的代码贴一下,还有很多不懂得地方 希望大家帮忙答疑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值